aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/codecs/onyx.c12
-rw-r--r--sound/aoa/codecs/tas.c4
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c4
-rw-r--r--sound/arm/aaci.c8
-rw-r--r--sound/arm/pxa2xx-pcm.c2
-rw-r--r--sound/atmel/ac97c.c87
-rw-r--r--sound/core/control.c388
-rw-r--r--sound/core/control_compat.c34
-rw-r--r--sound/core/init.c6
-rw-r--r--sound/core/pcm.c69
-rw-r--r--sound/core/pcm_compat.c5
-rw-r--r--sound/core/pcm_native.c309
-rw-r--r--sound/core/timer.c13
-rw-r--r--sound/drivers/aloop.c6
-rw-r--r--sound/drivers/dummy.c2
-rw-r--r--sound/drivers/ml403-ac97cr.c8
-rw-r--r--sound/drivers/mpu401/mpu401.c2
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c24
-rw-r--r--sound/drivers/opl3/opl3_lib.c4
-rw-r--r--sound/drivers/opl3/opl3_midi.c4
-rw-r--r--sound/drivers/pcsp/pcsp.c29
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c2
-rw-r--r--sound/drivers/vx/vx_core.c4
-rw-r--r--sound/drivers/vx/vx_pcm.c4
-rw-r--r--sound/firewire/bebob/bebob.h2
-rw-r--r--sound/firewire/bebob/bebob_focusrite.c6
-rw-r--r--sound/firewire/bebob/bebob_maudio.c2
-rw-r--r--sound/firewire/bebob/bebob_terratec.c2
-rw-r--r--sound/firewire/bebob/bebob_yamaha_terratec.c2
-rw-r--r--sound/firewire/dice/dice.c2
-rw-r--r--sound/firewire/fireface/ff-pcm.c20
-rw-r--r--sound/firewire/fireface/ff-protocol-ff400.c2
-rw-r--r--sound/firewire/fireface/ff.c2
-rw-r--r--sound/firewire/fireface/ff.h4
-rw-r--r--sound/firewire/fireworks/fireworks_proc.c2
-rw-r--r--sound/firewire/isight.c2
-rw-r--r--sound/firewire/motu/motu-midi.c4
-rw-r--r--sound/firewire/motu/motu-pcm.c6
-rw-r--r--sound/firewire/motu/motu-protocol-v2.c5
-rw-r--r--sound/firewire/motu/motu-protocol-v3.c5
-rw-r--r--sound/firewire/motu/motu-stream.c38
-rw-r--r--sound/firewire/motu/motu.c28
-rw-r--r--sound/firewire/motu/motu.h6
-rw-r--r--sound/firewire/oxfw/oxfw-scs1x.c11
-rw-r--r--sound/firewire/tascam/tascam.c2
-rw-r--r--sound/hda/hdac_i915.c2
-rw-r--r--sound/isa/ad1816a/ad1816a.c2
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c8
-rw-r--r--sound/isa/ad1848/ad1848.c18
-rw-r--r--sound/isa/als100.c15
-rw-r--r--sound/isa/azt2320.c2
-rw-r--r--sound/isa/cmi8330.c2
-rw-r--r--sound/isa/cs423x/cs4231.c18
-rw-r--r--sound/isa/cs423x/cs4236.c22
-rw-r--r--sound/isa/es1688/es1688.c2
-rw-r--r--sound/isa/es1688/es1688_lib.c8
-rw-r--r--sound/isa/es18xx.c12
-rw-r--r--sound/isa/gus/gus_pcm.c8
-rw-r--r--sound/isa/gus/interwave.c2
-rw-r--r--sound/isa/msnd/msnd.c8
-rw-r--r--sound/isa/msnd/msnd_pinnacle.c2
-rw-r--r--sound/isa/opl3sa2.c4
-rw-r--r--sound/isa/opti9xx/miro.c9
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c16
-rw-r--r--sound/isa/sb/emu8000_callback.c2
-rw-r--r--sound/isa/sb/emu8000_pcm.c4
-rw-r--r--sound/isa/sb/sb16.c2
-rw-r--r--sound/isa/sb/sb16_main.c8
-rw-r--r--sound/isa/sb/sb8_main.c8
-rw-r--r--sound/isa/sscape.c2
-rw-r--r--sound/isa/wavefront/wavefront.c2
-rw-r--r--sound/isa/wss/wss_lib.c8
-rw-r--r--sound/mips/hal2.c6
-rw-r--r--sound/mips/sgio2audio.c8
-rw-r--r--sound/parisc/harmony.c8
-rw-r--r--sound/pci/ad1889.c4
-rw-r--r--sound/pci/ali5451/ali5451.c12
-rw-r--r--sound/pci/als300.c4
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/asihpi/hpidebug.c4
-rw-r--r--sound/pci/atiixp.c4
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c10
-rw-r--r--sound/pci/aw2/aw2-alsa.c4
-rw-r--r--sound/pci/bt87x.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c10
-rw-r--r--sound/pci/cmipci.c31
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c4
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c4
-rw-r--r--sound/pci/ctxfi/cthw20k1.c2
-rw-r--r--sound/pci/ctxfi/cthw20k2.c2
-rw-r--r--sound/pci/ctxfi/ctpcm.c48
-rw-r--r--sound/pci/ctxfi/ctresource.c6
-rw-r--r--sound/pci/ctxfi/ctsrc.c6
-rw-r--r--sound/pci/echoaudio/echoaudio.c8
-rw-r--r--sound/pci/emu10k1/emu10k1x.c4
-rw-r--r--sound/pci/emu10k1/emupcm.c10
-rw-r--r--sound/pci/emu10k1/p16v.c4
-rw-r--r--sound/pci/ens1370.c6
-rw-r--r--sound/pci/es1938.c4
-rw-r--r--sound/pci/es1968.c4
-rw-r--r--sound/pci/fm801.c4
-rw-r--r--sound/pci/hda/dell_wmi_helper.c87
-rw-r--r--sound/pci/hda/hda_bind.c5
-rw-r--r--sound/pci/hda/hda_codec.c4
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_intel.c3
-rw-r--r--sound/pci/hda/patch_analog.c4
-rw-r--r--sound/pci/hda/patch_ca0132.c8
-rw-r--r--sound/pci/hda/patch_hdmi.c14
-rw-r--r--sound/pci/hda/patch_realtek.c17
-rw-r--r--sound/pci/hda/patch_sigmatel.c2
-rw-r--r--sound/pci/ice1712/delta.c24
-rw-r--r--sound/pci/ice1712/ews.c12
-rw-r--r--sound/pci/ice1712/hoontech.c43
-rw-r--r--sound/pci/ice1712/hoontech.h1
-rw-r--r--sound/pci/ice1712/juli.c2
-rw-r--r--sound/pci/ice1712/phase.c4
-rw-r--r--sound/pci/ice1712/quartet.c2
-rw-r--r--sound/pci/ice1712/revo.c20
-rw-r--r--sound/pci/intel8x0.c28
-rw-r--r--sound/pci/intel8x0m.c10
-rw-r--r--sound/pci/korg1212/korg1212.c4
-rw-r--r--sound/pci/lola/lola_pcm.c2
-rw-r--r--sound/pci/lx6464es/lx6464es.c2
-rw-r--r--sound/pci/maestro3.c4
-rw-r--r--sound/pci/mixart/mixart.c18
-rw-r--r--sound/pci/mixart/mixart.h4
-rw-r--r--sound/pci/nm256/nm256.c2
-rw-r--r--sound/pci/pcxhr/pcxhr.c25
-rw-r--r--sound/pci/pcxhr/pcxhr.h3
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c4
-rw-r--r--sound/pci/riptide/riptide.c4
-rw-r--r--sound/pci/rme32.c8
-rw-r--r--sound/pci/rme96.c51
-rw-r--r--sound/pci/rme9652/hdsp.c17
-rw-r--r--sound/pci/rme9652/hdspm.c90
-rw-r--r--sound/pci/rme9652/rme9652.c18
-rw-r--r--sound/pci/sis7019.c8
-rw-r--r--sound/pci/sonicvibes.c4
-rw-r--r--sound/pci/trident/trident_main.c20
-rw-r--r--sound/pci/via82xx.c2
-rw-r--r--sound/pci/via82xx_modem.c2
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c4
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c4
-rw-r--r--sound/ppc/pmac.c8
-rw-r--r--sound/ppc/snd_ps3.c2
-rw-r--r--sound/sh/aica.c4
-rw-r--r--sound/sh/sh_dac_audio.c6
-rw-r--r--sound/soc/atmel/atmel-classd.c1
-rw-r--r--sound/soc/atmel/atmel-pdmic.c1
-rw-r--r--sound/soc/au1x/db1200.c2
-rw-r--r--sound/soc/au1x/dbdma2.c2
-rw-r--r--sound/soc/au1x/dma.c2
-rw-r--r--sound/soc/au1x/psc-ac97.c2
-rw-r--r--sound/soc/au1x/psc-i2s.c2
-rw-r--r--sound/soc/bcm/cygnus-ssp.c237
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c2
-rw-r--r--sound/soc/blackfin/bf6xx-i2s.c2
-rw-r--r--sound/soc/blackfin/bf6xx-sport.c38
-rw-r--r--sound/soc/cirrus/edb93xx.c2
-rw-r--r--sound/soc/cirrus/snappercl15.c2
-rw-r--r--sound/soc/codecs/88pm860x-codec.c2
-rw-r--r--sound/soc/codecs/Kconfig20
-rw-r--r--sound/soc/codecs/Makefile8
-rw-r--r--sound/soc/codecs/ab8500-codec.c2
-rw-r--r--sound/soc/codecs/ac97.c2
-rw-r--r--sound/soc/codecs/ad1836.c2
-rw-r--r--sound/soc/codecs/ad193x.c2
-rw-r--r--sound/soc/codecs/ad1980.c2
-rw-r--r--sound/soc/codecs/ad73311.c2
-rw-r--r--sound/soc/codecs/adau1373.c2
-rw-r--r--sound/soc/codecs/adau1701.c2
-rw-r--r--sound/soc/codecs/adau1977.c8
-rw-r--r--sound/soc/codecs/adav80x.c2
-rw-r--r--sound/soc/codecs/ads117x.c2
-rw-r--r--sound/soc/codecs/ak4104.c2
-rw-r--r--sound/soc/codecs/ak4535.c2
-rw-r--r--sound/soc/codecs/ak4554.c2
-rw-r--r--sound/soc/codecs/ak4613.c2
-rw-r--r--sound/soc/codecs/ak4641.c2
-rw-r--r--sound/soc/codecs/ak4642.c2
-rw-r--r--sound/soc/codecs/ak4671.c2
-rw-r--r--sound/soc/codecs/ak5386.c2
-rw-r--r--sound/soc/codecs/alc5623.c2
-rw-r--r--sound/soc/codecs/arizona.c4
-rw-r--r--sound/soc/codecs/bt-sco.c2
-rw-r--r--sound/soc/codecs/cq93vc.c2
-rw-r--r--sound/soc/codecs/cs35l33.c14
-rw-r--r--sound/soc/codecs/cs35l34.c5
-rw-r--r--sound/soc/codecs/cs35l35.c2
-rw-r--r--sound/soc/codecs/cs4271.c2
-rw-r--r--sound/soc/codecs/cs42l42.c11
-rw-r--r--sound/soc/codecs/cs42l51.c2
-rw-r--r--sound/soc/codecs/cs43130.c2694
-rw-r--r--sound/soc/codecs/cs43130.h546
-rw-r--r--sound/soc/codecs/cs4349.c2
-rw-r--r--sound/soc/codecs/cs47l24.c6
-rw-r--r--sound/soc/codecs/cs53l30.c17
-rw-r--r--sound/soc/codecs/cx20442.c2
-rw-r--r--sound/soc/codecs/da7210.c2
-rw-r--r--sound/soc/codecs/da7213.c2
-rw-r--r--sound/soc/codecs/da7218.c2
-rw-r--r--sound/soc/codecs/da7219.c2
-rw-r--r--sound/soc/codecs/da732x.c2
-rw-r--r--sound/soc/codecs/da9055.c2
-rw-r--r--sound/soc/codecs/dmic.c54
-rw-r--r--sound/soc/codecs/es7134.c2
-rw-r--r--sound/soc/codecs/es8316.c4
-rw-r--r--sound/soc/codecs/es8328.c2
-rw-r--r--sound/soc/codecs/hdac_hdmi.c43
-rw-r--r--sound/soc/codecs/hdmi-codec.c47
-rw-r--r--sound/soc/codecs/ics43432.c2
-rw-r--r--sound/soc/codecs/inno_rk3036.c4
-rw-r--r--sound/soc/codecs/isabelle.c2
-rw-r--r--sound/soc/codecs/jz4740.c2
-rw-r--r--sound/soc/codecs/lm4857.c2
-rw-r--r--sound/soc/codecs/lm49453.c2
-rw-r--r--sound/soc/codecs/max9768.c2
-rw-r--r--sound/soc/codecs/max98088.c2
-rw-r--r--sound/soc/codecs/max98090.c2
-rw-r--r--sound/soc/codecs/max98095.c2
-rw-r--r--sound/soc/codecs/max98357a.c2
-rw-r--r--sound/soc/codecs/max98371.c14
-rw-r--r--sound/soc/codecs/max9850.c2
-rw-r--r--sound/soc/codecs/max9860.c2
-rw-r--r--sound/soc/codecs/max9867.c4
-rw-r--r--sound/soc/codecs/max98926.c8
-rw-r--r--sound/soc/codecs/max98927.c87
-rw-r--r--sound/soc/codecs/mc13783.c2
-rw-r--r--sound/soc/codecs/ml26124.c2
-rw-r--r--sound/soc/codecs/msm8916-wcd-analog.c415
-rw-r--r--sound/soc/codecs/msm8916-wcd-digital.c39
-rw-r--r--sound/soc/codecs/nau8540.c2
-rw-r--r--sound/soc/codecs/nau8810.c2
-rw-r--r--sound/soc/codecs/nau8824.c2
-rw-r--r--sound/soc/codecs/nau8825.c28
-rw-r--r--sound/soc/codecs/pcm1681.c2
-rw-r--r--sound/soc/codecs/pcm179x.c2
-rw-r--r--sound/soc/codecs/pcm3008.c2
-rw-r--r--sound/soc/codecs/pcm512x.c2
-rw-r--r--sound/soc/codecs/rt274.c1229
-rw-r--r--sound/soc/codecs/rt274.h217
-rw-r--r--sound/soc/codecs/rt286.c2
-rw-r--r--sound/soc/codecs/rt298.c2
-rw-r--r--sound/soc/codecs/rt5514-spi.c146
-rw-r--r--sound/soc/codecs/rt5514-spi.h7
-rw-r--r--sound/soc/codecs/rt5514.c174
-rw-r--r--sound/soc/codecs/rt5514.h22
-rw-r--r--sound/soc/codecs/rt5616.c4
-rw-r--r--sound/soc/codecs/rt5631.c2
-rw-r--r--sound/soc/codecs/rt5640.c2
-rw-r--r--sound/soc/codecs/rt5645.c45
-rw-r--r--sound/soc/codecs/rt5651.c2
-rw-r--r--sound/soc/codecs/rt5659.c4
-rw-r--r--sound/soc/codecs/rt5660.c2
-rw-r--r--sound/soc/codecs/rt5663.c264
-rw-r--r--sound/soc/codecs/rt5663.h2
-rw-r--r--sound/soc/codecs/rt5665.c55
-rw-r--r--sound/soc/codecs/rt5665.h21
-rw-r--r--sound/soc/codecs/rt5670.c62
-rw-r--r--sound/soc/codecs/rt5677.c82
-rw-r--r--sound/soc/codecs/rt5677.h30
-rw-r--r--sound/soc/codecs/sgtl5000.c2
-rw-r--r--sound/soc/codecs/si476x.c2
-rw-r--r--sound/soc/codecs/sirf-audio-codec.c12
-rw-r--r--sound/soc/codecs/sn95031.c2
-rw-r--r--sound/soc/codecs/spdif_receiver.c2
-rw-r--r--sound/soc/codecs/spdif_transmitter.c2
-rw-r--r--sound/soc/codecs/ssm2518.c2
-rw-r--r--sound/soc/codecs/ssm2602.c2
-rw-r--r--sound/soc/codecs/ssm4567.c2
-rw-r--r--sound/soc/codecs/sta32x.c3
-rw-r--r--sound/soc/codecs/stac9766.c2
-rw-r--r--sound/soc/codecs/tas2552.c13
-rw-r--r--sound/soc/codecs/tas5086.c2
-rw-r--r--sound/soc/codecs/tas5720.c4
-rw-r--r--sound/soc/codecs/tlv320aic23.c2
-rw-r--r--sound/soc/codecs/tlv320aic26.c2
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c2
-rw-r--r--sound/soc/codecs/tlv320aic32x4-i2c.c2
-rw-r--r--sound/soc/codecs/tlv320aic32x4-spi.c2
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c208
-rw-r--r--sound/soc/codecs/tlv320aic32x4.h3
-rw-r--r--sound/soc/codecs/tlv320aic3x.c47
-rw-r--r--sound/soc/codecs/tlv320aic3x.h8
-rw-r--r--sound/soc/codecs/tlv320dac33.c2
-rw-r--r--sound/soc/codecs/twl4030.c2
-rw-r--r--sound/soc/codecs/twl6040.c6
-rw-r--r--sound/soc/codecs/uda134x.c2
-rw-r--r--sound/soc/codecs/uda1380.c2
-rw-r--r--sound/soc/codecs/wl1273.c2
-rw-r--r--sound/soc/codecs/wm5102.c4
-rw-r--r--sound/soc/codecs/wm5110.c4
-rw-r--r--sound/soc/codecs/wm8523.c6
-rw-r--r--sound/soc/codecs/wm8524.c261
-rw-r--r--sound/soc/codecs/wm8804.c3
-rw-r--r--sound/soc/codecs/zx_aud96p22.c6
-rw-r--r--sound/soc/davinci/davinci-mcasp.c6
-rw-r--r--sound/soc/davinci/davinci-vcif.c5
-rw-r--r--sound/soc/dwc/dwc-i2s.c6
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c2
-rw-r--r--sound/soc/fsl/fsl_asrc.c2
-rw-r--r--sound/soc/fsl/fsl_asrc_dma.c6
-rw-r--r--sound/soc/fsl/fsl_dma.c11
-rw-r--r--sound/soc/fsl/fsl_esai.c2
-rw-r--r--sound/soc/fsl/fsl_spdif.c2
-rw-r--r--sound/soc/fsl/fsl_ssi.c4
-rw-r--r--sound/soc/fsl/imx-audmux.c16
-rw-r--r--sound/soc/fsl/imx-es8328.c3
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c6
-rw-r--r--sound/soc/fsl/mpc5200_dma.c4
-rw-r--r--sound/soc/generic/audio-graph-card.c3
-rw-r--r--sound/soc/generic/audio-graph-scu-card.c3
-rw-r--r--sound/soc/generic/simple-card-utils.c9
-rw-r--r--sound/soc/generic/simple-card.c10
-rw-r--r--sound/soc/generic/simple-scu-card.c5
-rw-r--r--sound/soc/hisilicon/hi6210-i2s.c2
-rw-r--r--sound/soc/img/img-i2s-in.c2
-rw-r--r--sound/soc/img/img-i2s-out.c2
-rw-r--r--sound/soc/img/img-parallel-out.c2
-rw-r--r--sound/soc/img/img-spdif-in.c2
-rw-r--r--sound/soc/img/img-spdif-out.c2
-rw-r--r--sound/soc/intel/Kconfig3
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c10
-rw-r--r--sound/soc/intel/atom/sst/sst_drv_interface.c4
-rw-r--r--sound/soc/intel/atom/sst/sst_pci.c2
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-pcm.c4
-rw-r--r--sound/soc/intel/boards/bxt_rt298.c86
-rw-r--r--sound/soc/intel/boards/byt-max98090.c12
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_max98927.c310
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c81
-rw-r--r--sound/soc/intel/boards/mfld_machine.c4
-rw-r--r--sound/soc/intel/haswell/sst-haswell-pcm.c2
-rw-r--r--sound/soc/intel/skylake/Makefile5
-rw-r--r--sound/soc/intel/skylake/bxt-sst.c14
-rw-r--r--sound/soc/intel/skylake/cnl-sst-dsp.c274
-rw-r--r--sound/soc/intel/skylake/cnl-sst-dsp.h112
-rw-r--r--sound/soc/intel/skylake/cnl-sst.c497
-rw-r--r--sound/soc/intel/skylake/skl-messages.c163
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c82
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c6
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c6
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h12
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c6
-rw-r--r--sound/soc/intel/skylake/skl-sst.c12
-rw-r--r--sound/soc/intel/skylake/skl-topology.c741
-rw-r--r--sound/soc/intel/skylake/skl-topology.h83
-rw-r--r--sound/soc/intel/skylake/skl.c32
-rw-r--r--sound/soc/intel/skylake/skl.h3
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c21
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c11
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c2
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-pcm.c15
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c1
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c1
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650.c1
-rw-r--r--sound/soc/mxs/mxs-saif.c13
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c1
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c4
-rw-r--r--sound/soc/omap/ams-delta.c10
-rw-r--r--sound/soc/omap/omap-pcm.c4
-rw-r--r--sound/soc/omap/omap-twl4030.c13
-rw-r--r--sound/soc/omap/rx51.c9
-rw-r--r--sound/soc/pxa/hx4700.c8
-rw-r--r--sound/soc/pxa/mmp-pcm.c4
-rw-r--r--sound/soc/pxa/mmp-sspa.c2
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c4
-rw-r--r--sound/soc/qcom/apq8016_sbc.c58
-rw-r--r--sound/soc/qcom/lpass-platform.c4
-rw-r--r--sound/soc/qcom/storm.c1
-rw-r--r--sound/soc/rockchip/Kconfig2
-rw-r--r--sound/soc/rockchip/rk3288_hdmi_analog.c4
-rw-r--r--sound/soc/rockchip/rk3399_gru_sound.c270
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c4
-rw-r--r--sound/soc/rockchip/rockchip_pdm.c2
-rw-r--r--sound/soc/samsung/h1940_uda1380.c9
-rw-r--r--sound/soc/samsung/i2s.c45
-rw-r--r--sound/soc/samsung/idma.c4
-rw-r--r--sound/soc/samsung/jive_wm8750.c2
-rw-r--r--sound/soc/samsung/odroid.c44
-rw-r--r--sound/soc/samsung/pcm.c8
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c10
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c14
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.h7
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c15
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c11
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c2
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c3
-rw-r--r--sound/soc/samsung/smartq_wm8987.c9
-rw-r--r--sound/soc/samsung/smdk_spdif.c2
-rw-r--r--sound/soc/samsung/spdif.c8
-rw-r--r--sound/soc/samsung/tm2_wm5110.c4
-rw-r--r--sound/soc/sh/dma-sh7760.c6
-rw-r--r--sound/soc/sh/fsi.c12
-rw-r--r--sound/soc/sh/migor.c2
-rw-r--r--sound/soc/sh/rcar/adg.c11
-rw-r--r--sound/soc/sh/rcar/core.c109
-rw-r--r--sound/soc/sh/rcar/ctu.c5
-rw-r--r--sound/soc/sh/rcar/dma.c2
-rw-r--r--sound/soc/sh/rcar/dvc.c5
-rw-r--r--sound/soc/sh/rcar/gen.c4
-rw-r--r--sound/soc/sh/rcar/mix.c5
-rw-r--r--sound/soc/sh/rcar/rsnd.h1
-rw-r--r--sound/soc/sh/rcar/src.c14
-rw-r--r--sound/soc/sh/rcar/ssi.c141
-rw-r--r--sound/soc/sh/rcar/ssiu.c2
-rw-r--r--sound/soc/sh/siu_dai.c2
-rw-r--r--sound/soc/sh/siu_pcm.c2
-rw-r--r--sound/soc/soc-compress.c23
-rw-r--r--sound/soc/soc-core.c323
-rw-r--r--sound/soc/soc-jack.c76
-rw-r--r--sound/soc/soc-pcm.c43
-rw-r--r--sound/soc/soc-utils.c2
-rw-r--r--sound/soc/spear/spdif_in.c12
-rw-r--r--sound/soc/spear/spdif_out.c4
-rw-r--r--sound/soc/stm/stm32_i2s.c2
-rw-r--r--sound/soc/stm/stm32_sai.c2
-rw-r--r--sound/soc/stm/stm32_spdifrx.c2
-rw-r--r--sound/soc/sunxi/sun4i-codec.c15
-rw-r--r--sound/soc/sunxi/sun4i-i2s.c455
-rw-r--r--sound/soc/sunxi/sun4i-spdif.c14
-rw-r--r--sound/soc/sunxi/sun8i-codec.c4
-rw-r--r--sound/soc/tegra/Kconfig42
-rw-r--r--sound/soc/tegra/tegra30_ahub.c4
-rw-r--r--sound/soc/tegra/tegra30_i2s.c2
-rw-r--r--sound/soc/tegra/tegra_alc5632.c14
-rw-r--r--sound/soc/tegra/tegra_max98090.c19
-rw-r--r--sound/soc/tegra/tegra_rt5640.c14
-rw-r--r--sound/soc/tegra/tegra_rt5677.c19
-rw-r--r--sound/soc/tegra/tegra_sgtl5000.c1
-rw-r--r--sound/soc/tegra/tegra_wm8753.c1
-rw-r--r--sound/soc/tegra/tegra_wm8903.c7
-rw-r--r--sound/soc/tegra/tegra_wm9712.c1
-rw-r--r--sound/soc/tegra/trimslice.c1
-rw-r--r--sound/soc/txx9/txx9aclc.c4
-rw-r--r--sound/soc/ux500/mop500.c1
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c2
-rw-r--r--sound/soc/zte/zx-i2s.c2
-rw-r--r--sound/soc/zte/zx-spdif.c2
-rw-r--r--sound/soc/zte/zx-tdm.c2
-rw-r--r--sound/sparc/amd7930.c6
-rw-r--r--sound/sparc/cs4231.c8
-rw-r--r--sound/sparc/dbri.c4
-rw-r--r--sound/spi/at73c213.c2
-rw-r--r--sound/synth/emux/emux_seq.c20
-rw-r--r--sound/usb/6fire/chip.c2
-rw-r--r--sound/usb/6fire/pcm.c2
-rw-r--r--sound/usb/bcd2000/bcd2000.c2
-rw-r--r--sound/usb/caiaq/audio.c5
-rw-r--r--sound/usb/caiaq/device.c2
-rw-r--r--sound/usb/card.c4
-rw-r--r--sound/usb/hiface/pcm.c2
-rw-r--r--sound/usb/midi.c26
-rw-r--r--sound/usb/misc/ua101.c6
-rw-r--r--sound/usb/mixer.c20
-rw-r--r--sound/usb/pcm.c6
-rw-r--r--sound/usb/quirks.c5
-rw-r--r--sound/usb/stream.c4
-rw-r--r--sound/usb/usx2y/us122l.c2
-rw-r--r--sound/usb/usx2y/usb_stream.c4
-rw-r--r--sound/usb/usx2y/usbusx2y.c2
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c11
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
467 files changed, 11713 insertions, 2941 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index a04edff8b729..d2d96ca082b7 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -167,7 +167,7 @@ static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
return 1;
}
-static struct snd_kcontrol_new volume_control = {
+static const struct snd_kcontrol_new volume_control = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Volume",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -229,7 +229,7 @@ static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
return n != v;
}
-static struct snd_kcontrol_new inputgain_control = {
+static const struct snd_kcontrol_new inputgain_control = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Capture Volume",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -284,7 +284,7 @@ static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
return 1;
}
-static struct snd_kcontrol_new capture_source_control = {
+static const struct snd_kcontrol_new capture_source_control = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
/* If we name this 'Input Source', it properly shows up in
* alsamixer as a selection, * but it's shown under the
@@ -348,7 +348,7 @@ static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
return !err ? (v != c) : err;
}
-static struct snd_kcontrol_new mute_control = {
+static const struct snd_kcontrol_new mute_control = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -476,7 +476,7 @@ static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static struct snd_kcontrol_new onyx_spdif_mask = {
+static const struct snd_kcontrol_new onyx_spdif_mask = {
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
@@ -533,7 +533,7 @@ static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
return 1;
}
-static struct snd_kcontrol_new onyx_spdif_ctrl = {
+static const struct snd_kcontrol_new onyx_spdif_ctrl = {
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 733b6365dad6..15c05755d270 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -905,8 +905,8 @@ static int tas_i2c_probe(struct i2c_client *client,
goto fail;
}
printk(KERN_DEBUG
- "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n",
- (unsigned int)client->addr, node->full_name);
+ "snd-aoa-codec-tas: tas found, addr 0x%02x on %pOF\n",
+ (unsigned int)client->addr, node);
return 0;
fail:
mutex_destroy(&tas->mtx);
diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c
index 053b09c79053..e618531757e0 100644
--- a/sound/aoa/soundbus/i2sbus/pcm.c
+++ b/sound/aoa/soundbus/i2sbus/pcm.c
@@ -778,7 +778,7 @@ static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
return i2sbus_pcm_pointer(i2sdev, 0);
}
-static struct snd_pcm_ops i2sbus_playback_ops = {
+static const struct snd_pcm_ops i2sbus_playback_ops = {
.open = i2sbus_playback_open,
.close = i2sbus_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -848,7 +848,7 @@ static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
return i2sbus_pcm_pointer(i2sdev, 1);
}
-static struct snd_pcm_ops i2sbus_record_ops = {
+static const struct snd_pcm_ops i2sbus_record_ops = {
.open = i2sbus_record_open,
.close = i2sbus_record_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 4140b1b95054..0114ffed56dd 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -348,7 +348,7 @@ static irqreturn_t aaci_irq(int irq, void *devid)
/*
* ALSA support.
*/
-static struct snd_pcm_hardware aaci_hw_info = {
+static const struct snd_pcm_hardware aaci_hw_info = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -635,7 +635,7 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
return ret;
}
-static struct snd_pcm_ops aaci_playback_ops = {
+static const struct snd_pcm_ops aaci_playback_ops = {
.open = aaci_pcm_open,
.close = aaci_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -738,7 +738,7 @@ static int aaci_pcm_capture_prepare(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_ops aaci_capture_ops = {
+static const struct snd_pcm_ops aaci_capture_ops = {
.open = aaci_pcm_open,
.close = aaci_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -786,7 +786,7 @@ static SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume);
#endif
-static struct ac97_pcm ac97_defs[] = {
+static const struct ac97_pcm ac97_defs[] = {
[0] = { /* Front PCM */
.exclusive = 1,
.r = {
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
index 83fcfac97739..1c6f4b436de3 100644
--- a/sound/arm/pxa2xx-pcm.c
+++ b/sound/arm/pxa2xx-pcm.c
@@ -68,7 +68,7 @@ static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
return __pxa2xx_pcm_close(substream);
}
-static struct snd_pcm_ops pxa2xx_pcm_ops = {
+static const struct snd_pcm_ops pxa2xx_pcm_ops = {
.open = pxa2xx_pcm_open,
.close = pxa2xx_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index 9d2c9d9af688..380025887aef 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -12,16 +12,15 @@
#include <linux/bitmap.h>
#include <linux/device.h>
#include <linux/atmel_pdc.h>
+#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
-#include <linux/gpio.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/of.h>
-#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <sound/core.h>
@@ -29,7 +28,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/ac97_codec.h>
-#include <sound/atmel-ac97c.h>
#include <sound/memalloc.h>
#include "ac97c.h"
@@ -56,7 +54,7 @@ struct atmel_ac97c {
void __iomem *regs;
int irq;
int opened;
- int reset_pin;
+ struct gpio_desc *reset_pin;
};
#define get_chip(card) ((struct atmel_ac97c *)(card)->private_data)
@@ -66,7 +64,7 @@ struct atmel_ac97c {
#define ac97c_readl(chip, reg) \
__raw_readl((chip)->regs + AC97C_##reg)
-static struct snd_pcm_hardware atmel_ac97c_hw = {
+static const struct snd_pcm_hardware atmel_ac97c_hw = {
.info = (SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_MMAP_VALID
| SNDRV_PCM_INFO_INTERLEAVED
@@ -461,7 +459,7 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
return frames;
}
-static struct snd_pcm_ops atmel_ac97_playback_ops = {
+static const struct snd_pcm_ops atmel_ac97_playback_ops = {
.open = atmel_ac97c_playback_open,
.close = atmel_ac97c_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -472,7 +470,7 @@ static struct snd_pcm_ops atmel_ac97_playback_ops = {
.pointer = atmel_ac97c_playback_pointer,
};
-static struct snd_pcm_ops atmel_ac97_capture_ops = {
+static const struct snd_pcm_ops atmel_ac97_capture_ops = {
.open = atmel_ac97c_capture_open,
.close = atmel_ac97c_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -558,7 +556,7 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
return retval;
}
-static struct ac97_pcm at91_ac97_pcm_defs[] = {
+static const struct ac97_pcm at91_ac97_pcm_defs[] = {
/* Playback */
{
.exclusive = 1,
@@ -700,11 +698,11 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip)
ac97c_writel(chip, CAMR, 0);
ac97c_writel(chip, COMR, 0);
- if (gpio_is_valid(chip->reset_pin)) {
- gpio_set_value(chip->reset_pin, 0);
+ if (!IS_ERR(chip->reset_pin)) {
+ gpiod_set_value(chip->reset_pin, 0);
/* AC97 v2.2 specifications says minimum 1 us. */
udelay(2);
- gpio_set_value(chip->reset_pin, 1);
+ gpiod_set_value(chip->reset_pin, 1);
} else {
ac97c_writel(chip, MR, AC97C_MR_WRST | AC97C_MR_ENA);
udelay(2);
@@ -712,45 +710,18 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip)
}
}
-#ifdef CONFIG_OF
static const struct of_device_id atmel_ac97c_dt_ids[] = {
{ .compatible = "atmel,at91sam9263-ac97c", },
{ }
};
MODULE_DEVICE_TABLE(of, atmel_ac97c_dt_ids);
-static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev)
-{
- struct ac97c_platform_data *pdata;
- struct device_node *node = dev->of_node;
-
- if (!node) {
- dev_err(dev, "Device does not have associated DT data\n");
- return ERR_PTR(-EINVAL);
- }
-
- pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return ERR_PTR(-ENOMEM);
-
- pdata->reset_pin = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
-
- return pdata;
-}
-#else
-static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev)
-{
- dev_err(dev, "no platform data defined\n");
- return ERR_PTR(-ENXIO);
-}
-#endif
-
static int atmel_ac97c_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct snd_card *card;
struct atmel_ac97c *chip;
struct resource *regs;
- struct ac97c_platform_data *pdata;
struct clk *pclk;
static struct snd_ac97_bus_ops ops = {
.write = atmel_ac97c_write,
@@ -765,13 +736,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
return -ENXIO;
}
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- pdata = atmel_ac97c_probe_dt(&pdev->dev);
- if (IS_ERR(pdata))
- return PTR_ERR(pdata);
- }
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_dbg(&pdev->dev, "could not get irq: %d\n", irq);
@@ -783,7 +747,9 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "no peripheral clock\n");
return PTR_ERR(pclk);
}
- clk_prepare_enable(pclk);
+ retval = clk_prepare_enable(pclk);
+ if (retval)
+ goto err_prepare_enable;
retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
SNDRV_DEFAULT_STR1, THIS_MODULE,
@@ -819,17 +785,9 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
goto err_ioremap;
}
- if (gpio_is_valid(pdata->reset_pin)) {
- if (gpio_request(pdata->reset_pin, "reset_pin")) {
- dev_dbg(&pdev->dev, "reset pin not available\n");
- chip->reset_pin = -ENODEV;
- } else {
- gpio_direction_output(pdata->reset_pin, 1);
- chip->reset_pin = pdata->reset_pin;
- }
- } else {
- chip->reset_pin = -EINVAL;
- }
+ chip->reset_pin = devm_gpiod_get_index(dev, "ac97", 2, GPIOD_OUT_HIGH);
+ if (IS_ERR(chip->reset_pin))
+ dev_dbg(dev, "reset pin not available\n");
atmel_ac97c_reset(chip);
@@ -869,9 +827,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
return 0;
err_ac97_bus:
- if (gpio_is_valid(chip->reset_pin))
- gpio_free(chip->reset_pin);
-
iounmap(chip->regs);
err_ioremap:
free_irq(irq, chip);
@@ -879,6 +834,7 @@ err_request_irq:
snd_card_free(card);
err_snd_card_new:
clk_disable_unprepare(pclk);
+err_prepare_enable:
clk_put(pclk);
return retval;
}
@@ -897,9 +853,9 @@ static int atmel_ac97c_resume(struct device *pdev)
{
struct snd_card *card = dev_get_drvdata(pdev);
struct atmel_ac97c *chip = card->private_data;
+ int ret = clk_prepare_enable(chip->pclk);
- clk_prepare_enable(chip->pclk);
- return 0;
+ return ret;
}
static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume);
@@ -913,9 +869,6 @@ static int atmel_ac97c_remove(struct platform_device *pdev)
struct snd_card *card = platform_get_drvdata(pdev);
struct atmel_ac97c *chip = get_chip(card);
- if (gpio_is_valid(chip->reset_pin))
- gpio_free(chip->reset_pin);
-
ac97c_writel(chip, CAMR, 0);
ac97c_writel(chip, COMR, 0);
ac97c_writel(chip, MR, 0);
@@ -936,7 +889,7 @@ static struct platform_driver atmel_ac97c_driver = {
.driver = {
.name = "atmel_ac97c",
.pm = ATMEL_AC97C_PM_OPS,
- .of_match_table = of_match_ptr(atmel_ac97c_dt_ids),
+ .of_match_table = atmel_ac97c_dt_ids,
},
};
module_platform_driver(atmel_ac97c_driver);
diff --git a/sound/core/control.c b/sound/core/control.c
index 4525e127afd9..56b3e2d49c82 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -864,14 +864,14 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
- snd_power_lock(ctl->card);
result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
- if (result >= 0)
- result = snd_ctl_elem_info(ctl, &info);
- snd_power_unlock(ctl->card);
- if (result >= 0)
- if (copy_to_user(_info, &info, sizeof(info)))
- return -EFAULT;
+ if (result < 0)
+ return result;
+ result = snd_ctl_elem_info(ctl, &info);
+ if (result < 0)
+ return result;
+ if (copy_to_user(_info, &info, sizeof(info)))
+ return -EFAULT;
return result;
}
@@ -881,24 +881,18 @@ static int snd_ctl_elem_read(struct snd_card *card,
struct snd_kcontrol *kctl;
struct snd_kcontrol_volatile *vd;
unsigned int index_offset;
- int result;
- down_read(&card->controls_rwsem);
kctl = snd_ctl_find_id(card, &control->id);
- if (kctl == NULL) {
- result = -ENOENT;
- } else {
- index_offset = snd_ctl_get_ioff(kctl, &control->id);
- vd = &kctl->vd[index_offset];
- if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) &&
- kctl->get != NULL) {
- snd_ctl_build_ioff(&control->id, kctl, index_offset);
- result = kctl->get(kctl, control);
- } else
- result = -EPERM;
- }
- up_read(&card->controls_rwsem);
- return result;
+ if (kctl == NULL)
+ return -ENOENT;
+
+ index_offset = snd_ctl_get_ioff(kctl, &control->id);
+ vd = &kctl->vd[index_offset];
+ if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get == NULL)
+ return -EPERM;
+
+ snd_ctl_build_ioff(&control->id, kctl, index_offset);
+ return kctl->get(kctl, control);
}
static int snd_ctl_elem_read_user(struct snd_card *card,
@@ -911,14 +905,19 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
if (IS_ERR(control))
return PTR_ERR(control);
- snd_power_lock(card);
result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result >= 0)
- result = snd_ctl_elem_read(card, control);
- snd_power_unlock(card);
- if (result >= 0)
- if (copy_to_user(_control, control, sizeof(*control)))
- result = -EFAULT;
+ if (result < 0)
+ goto error;
+
+ down_read(&card->controls_rwsem);
+ result = snd_ctl_elem_read(card, control);
+ up_read(&card->controls_rwsem);
+ if (result < 0)
+ goto error;
+
+ if (copy_to_user(_control, control, sizeof(*control)))
+ result = -EFAULT;
+ error:
kfree(control);
return result;
}
@@ -931,30 +930,28 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
unsigned int index_offset;
int result;
- down_read(&card->controls_rwsem);
kctl = snd_ctl_find_id(card, &control->id);
- if (kctl == NULL) {
- result = -ENOENT;
- } else {
- index_offset = snd_ctl_get_ioff(kctl, &control->id);
- vd = &kctl->vd[index_offset];
- if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
- kctl->put == NULL ||
- (file && vd->owner && vd->owner != file)) {
- result = -EPERM;
- } else {
- snd_ctl_build_ioff(&control->id, kctl, index_offset);
- result = kctl->put(kctl, control);
- }
- if (result > 0) {
- struct snd_ctl_elem_id id = control->id;
- up_read(&card->controls_rwsem);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
- return 0;
- }
+ if (kctl == NULL)
+ return -ENOENT;
+
+ index_offset = snd_ctl_get_ioff(kctl, &control->id);
+ vd = &kctl->vd[index_offset];
+ if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kctl->put == NULL ||
+ (file && vd->owner && vd->owner != file)) {
+ return -EPERM;
}
- up_read(&card->controls_rwsem);
- return result;
+
+ snd_ctl_build_ioff(&control->id, kctl, index_offset);
+ result = kctl->put(kctl, control);
+ if (result < 0)
+ return result;
+
+ if (result > 0) {
+ struct snd_ctl_elem_id id = control->id;
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
+ }
+
+ return 0;
}
static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
@@ -969,14 +966,19 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
return PTR_ERR(control);
card = file->card;
- snd_power_lock(card);
result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (result >= 0)
- result = snd_ctl_elem_write(card, file, control);
- snd_power_unlock(card);
- if (result >= 0)
- if (copy_to_user(_control, control, sizeof(*control)))
- result = -EFAULT;
+ if (result < 0)
+ goto error;
+
+ down_write(&card->controls_rwsem);
+ result = snd_ctl_elem_write(card, file, control);
+ up_write(&card->controls_rwsem);
+ if (result < 0)
+ goto error;
+
+ if (copy_to_user(_control, control, sizeof(*control)))
+ result = -EFAULT;
+ error:
kfree(control);
return result;
}
@@ -1095,9 +1097,7 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
char *src = ue->elem_data +
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
- mutex_lock(&ue->card->user_ctl_lock);
memcpy(&ucontrol->value, src, size);
- mutex_unlock(&ue->card->user_ctl_lock);
return 0;
}
@@ -1110,60 +1110,83 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
char *dst = ue->elem_data +
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
- mutex_lock(&ue->card->user_ctl_lock);
change = memcmp(&ucontrol->value, dst, size) != 0;
if (change)
memcpy(dst, &ucontrol->value, size);
- mutex_unlock(&ue->card->user_ctl_lock);
return change;
}
-static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
- int op_flag,
- unsigned int size,
- unsigned int __user *tlv)
+static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
+ unsigned int size)
{
- struct user_element *ue = kcontrol->private_data;
- int change = 0;
- void *new_data;
+ struct user_element *ue = kctl->private_data;
+ unsigned int *container;
+ struct snd_ctl_elem_id id;
+ unsigned int mask = 0;
+ int i;
+ int change;
- if (op_flag == SNDRV_CTL_TLV_OP_WRITE) {
- if (size > 1024 * 128) /* sane value */
- return -EINVAL;
+ if (size > 1024 * 128) /* sane value */
+ return -EINVAL;
- new_data = memdup_user(tlv, size);
- if (IS_ERR(new_data))
- return PTR_ERR(new_data);
- mutex_lock(&ue->card->user_ctl_lock);
- change = ue->tlv_data_size != size;
- if (!change)
- change = memcmp(ue->tlv_data, new_data, size) != 0;
- kfree(ue->tlv_data);
- ue->tlv_data = new_data;
- ue->tlv_data_size = size;
- mutex_unlock(&ue->card->user_ctl_lock);
- } else {
- int ret = 0;
+ container = memdup_user(buf, size);
+ if (IS_ERR(container))
+ return PTR_ERR(container);
- mutex_lock(&ue->card->user_ctl_lock);
- if (!ue->tlv_data_size || !ue->tlv_data) {
- ret = -ENXIO;
- goto err_unlock;
- }
- if (size < ue->tlv_data_size) {
- ret = -ENOSPC;
- goto err_unlock;
- }
- if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
- ret = -EFAULT;
-err_unlock:
- mutex_unlock(&ue->card->user_ctl_lock);
- if (ret)
- return ret;
+ change = ue->tlv_data_size != size;
+ if (!change)
+ change = memcmp(ue->tlv_data, container, size) != 0;
+ if (!change) {
+ kfree(container);
+ return 0;
}
+
+ if (ue->tlv_data == NULL) {
+ /* Now TLV data is available. */
+ for (i = 0; i < kctl->count; ++i)
+ kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+ mask = SNDRV_CTL_EVENT_MASK_INFO;
+ }
+
+ kfree(ue->tlv_data);
+ ue->tlv_data = container;
+ ue->tlv_data_size = size;
+
+ mask |= SNDRV_CTL_EVENT_MASK_TLV;
+ for (i = 0; i < kctl->count; ++i) {
+ snd_ctl_build_ioff(&id, kctl, i);
+ snd_ctl_notify(ue->card, mask, &id);
+ }
+
return change;
}
+static int read_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
+ unsigned int size)
+{
+ struct user_element *ue = kctl->private_data;
+
+ if (ue->tlv_data_size == 0 || ue->tlv_data == NULL)
+ return -ENXIO;
+
+ if (size < ue->tlv_data_size)
+ return -ENOSPC;
+
+ if (copy_to_user(buf, ue->tlv_data, ue->tlv_data_size))
+ return -EFAULT;
+
+ return 0;
+}
+
+static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kctl, int op_flag,
+ unsigned int size, unsigned int __user *buf)
+{
+ if (op_flag == SNDRV_CTL_TLV_OP_WRITE)
+ return replace_user_tlv(kctl, buf, size);
+ else
+ return read_user_tlv(kctl, buf, size);
+}
+
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
{
char *names, *p;
@@ -1267,8 +1290,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
access &= (SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_INACTIVE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE);
- if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)
+ SNDRV_CTL_ELEM_ACCESS_TLV_WRITE);
+
+ /* In initial state, nothing is available as TLV container. */
+ if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
access |= SNDRV_CTL_ELEM_ACCESS_USER;
@@ -1331,7 +1356,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
kctl->get = snd_ctl_elem_user_get;
if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
kctl->put = snd_ctl_elem_user_put;
- if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)
+ if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
kctl->tlv.c = snd_ctl_elem_user_tlv;
/* This function manage to free the instance on failure. */
@@ -1405,71 +1430,107 @@ static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
return 0;
}
+static int call_tlv_handler(struct snd_ctl_file *file, int op_flag,
+ struct snd_kcontrol *kctl,
+ struct snd_ctl_elem_id *id,
+ unsigned int __user *buf, unsigned int size)
+{
+ static const struct {
+ int op;
+ int perm;
+ } pairs[] = {
+ {SNDRV_CTL_TLV_OP_READ, SNDRV_CTL_ELEM_ACCESS_TLV_READ},
+ {SNDRV_CTL_TLV_OP_WRITE, SNDRV_CTL_ELEM_ACCESS_TLV_WRITE},
+ {SNDRV_CTL_TLV_OP_CMD, SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND},
+ };
+ struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)];
+ int i;
+
+ /* Check support of the request for this element. */
+ for (i = 0; i < ARRAY_SIZE(pairs); ++i) {
+ if (op_flag == pairs[i].op && (vd->access & pairs[i].perm))
+ break;
+ }
+ if (i == ARRAY_SIZE(pairs))
+ return -ENXIO;
+
+ if (kctl->tlv.c == NULL)
+ return -ENXIO;
+
+ /* When locked, this is unavailable. */
+ if (vd->owner != NULL && vd->owner != file)
+ return -EPERM;
+
+ return kctl->tlv.c(kctl, op_flag, size, buf);
+}
+
+static int read_tlv_buf(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id,
+ unsigned int __user *buf, unsigned int size)
+{
+ struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)];
+ unsigned int len;
+
+ if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ))
+ return -ENXIO;
+
+ if (kctl->tlv.p == NULL)
+ return -ENXIO;
+
+ len = sizeof(unsigned int) * 2 + kctl->tlv.p[1];
+ if (size < len)
+ return -ENOMEM;
+
+ if (copy_to_user(buf, kctl->tlv.p, len))
+ return -EFAULT;
+
+ return 0;
+}
+
static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
- struct snd_ctl_tlv __user *_tlv,
+ struct snd_ctl_tlv __user *buf,
int op_flag)
{
- struct snd_card *card = file->card;
- struct snd_ctl_tlv tlv;
+ struct snd_ctl_tlv header;
+ unsigned int *container;
+ unsigned int container_size;
struct snd_kcontrol *kctl;
+ struct snd_ctl_elem_id id;
struct snd_kcontrol_volatile *vd;
- unsigned int len;
- int err = 0;
- if (copy_from_user(&tlv, _tlv, sizeof(tlv)))
+ if (copy_from_user(&header, buf, sizeof(header)))
return -EFAULT;
- if (tlv.length < sizeof(unsigned int) * 2)
+
+ /* In design of control core, numerical ID starts at 1. */
+ if (header.numid == 0)
return -EINVAL;
- if (!tlv.numid)
+
+ /* At least, container should include type and length fields. */
+ if (header.length < sizeof(unsigned int) * 2)
return -EINVAL;
- down_read(&card->controls_rwsem);
- kctl = snd_ctl_find_numid(card, tlv.numid);
- if (kctl == NULL) {
- err = -ENOENT;
- goto __kctl_end;
- }
- if (kctl->tlv.p == NULL) {
- err = -ENXIO;
- goto __kctl_end;
- }
- vd = &kctl->vd[tlv.numid - kctl->id.numid];
- if ((op_flag == SNDRV_CTL_TLV_OP_READ &&
- (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) == 0) ||
- (op_flag == SNDRV_CTL_TLV_OP_WRITE &&
- (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) == 0) ||
- (op_flag == SNDRV_CTL_TLV_OP_CMD &&
- (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) == 0)) {
- err = -ENXIO;
- goto __kctl_end;
- }
+ container_size = header.length;
+ container = buf->tlv;
+
+ kctl = snd_ctl_find_numid(file->card, header.numid);
+ if (kctl == NULL)
+ return -ENOENT;
+
+ /* Calculate index of the element in this set. */
+ id = kctl->id;
+ snd_ctl_build_ioff(&id, kctl, header.numid - id.numid);
+ vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
+
if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
- if (vd->owner != NULL && vd->owner != file) {
- err = -EPERM;
- goto __kctl_end;
- }
- err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
- if (err > 0) {
- struct snd_ctl_elem_id id = kctl->id;
- up_read(&card->controls_rwsem);
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id);
- return 0;
- }
+ return call_tlv_handler(file, op_flag, kctl, &id, container,
+ container_size);
} else {
- if (op_flag != SNDRV_CTL_TLV_OP_READ) {
- err = -ENXIO;
- goto __kctl_end;
+ if (op_flag == SNDRV_CTL_TLV_OP_READ) {
+ return read_tlv_buf(kctl, &id, container,
+ container_size);
}
- len = kctl->tlv.p[1] + 2 * sizeof(unsigned int);
- if (tlv.length < len) {
- err = -ENOMEM;
- goto __kctl_end;
- }
- if (copy_to_user(_tlv->tlv, kctl->tlv.p, len))
- err = -EFAULT;
}
- __kctl_end:
- up_read(&card->controls_rwsem);
- return err;
+
+ /* Not supported. */
+ return -ENXIO;
}
static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -1511,11 +1572,20 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
return snd_ctl_subscribe_events(ctl, ip);
case SNDRV_CTL_IOCTL_TLV_READ:
- return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ);
+ down_read(&ctl->card->controls_rwsem);
+ err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ);
+ up_read(&ctl->card->controls_rwsem);
+ return err;
case SNDRV_CTL_IOCTL_TLV_WRITE:
- return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE);
+ down_write(&ctl->card->controls_rwsem);
+ err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE);
+ up_write(&ctl->card->controls_rwsem);
+ return err;
case SNDRV_CTL_IOCTL_TLV_COMMAND:
- return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD);
+ down_write(&ctl->card->controls_rwsem);
+ err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD);
+ up_write(&ctl->card->controls_rwsem);
+ return err;
case SNDRV_CTL_IOCTL_POWER:
return -ENOPROTOOPT;
case SNDRV_CTL_IOCTL_POWER_STATE:
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 1fa70766ffab..a848836a5de0 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -111,12 +111,10 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
goto error;
- snd_power_lock(ctl->card);
err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
- if (err >= 0)
- err = snd_ctl_elem_info(ctl, data);
- snd_power_unlock(ctl->card);
-
+ if (err < 0)
+ goto error;
+ err = snd_ctl_elem_info(ctl, data);
if (err < 0)
goto error;
/* restore info to 32bit */
@@ -315,14 +313,13 @@ static int ctl_elem_read_user(struct snd_card *card,
if (err < 0)
goto error;
- snd_power_lock(card);
err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (err >= 0)
- err = snd_ctl_elem_read(card, data);
- snd_power_unlock(card);
- if (err >= 0)
- err = copy_ctl_value_to_user(userdata, valuep, data,
- type, count);
+ if (err < 0)
+ goto error;
+ err = snd_ctl_elem_read(card, data);
+ if (err < 0)
+ goto error;
+ err = copy_ctl_value_to_user(userdata, valuep, data, type, count);
error:
kfree(data);
return err;
@@ -344,14 +341,13 @@ static int ctl_elem_write_user(struct snd_ctl_file *file,
if (err < 0)
goto error;
- snd_power_lock(card);
err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (err >= 0)
- err = snd_ctl_elem_write(card, file, data);
- snd_power_unlock(card);
- if (err >= 0)
- err = copy_ctl_value_to_user(userdata, valuep, data,
- type, count);
+ if (err < 0)
+ goto error;
+ err = snd_ctl_elem_write(card, file, data);
+ if (err < 0)
+ goto error;
+ err = copy_ctl_value_to_user(userdata, valuep, data, type, count);
error:
kfree(data);
return err;
diff --git a/sound/core/init.c b/sound/core/init.c
index b4365bcf28a7..32ebe2f6bc59 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -248,13 +248,11 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
INIT_LIST_HEAD(&card->devices);
init_rwsem(&card->controls_rwsem);
rwlock_init(&card->ctl_files_rwlock);
- mutex_init(&card->user_ctl_lock);
INIT_LIST_HEAD(&card->controls);
INIT_LIST_HEAD(&card->ctl_files);
spin_lock_init(&card->files_lock);
INIT_LIST_HEAD(&card->files_list);
#ifdef CONFIG_PM
- mutex_init(&card->power_lock);
init_waitqueue_head(&card->power_sleep);
#endif
@@ -979,8 +977,6 @@ EXPORT_SYMBOL(snd_card_file_remove);
* Waits until the power-state is changed.
*
* Return: Zero if successful, or a negative error code.
- *
- * Note: the power lock must be active before call.
*/
int snd_power_wait(struct snd_card *card, unsigned int power_state)
{
@@ -1000,9 +996,7 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state)
if (snd_power_get_state(card) == power_state)
break;
set_current_state(TASK_UNINTERRUPTIBLE);
- snd_power_unlock(card);
schedule_timeout(30 * HZ);
- snd_power_lock(card);
}
remove_wait_queue(&card->power_sleep, &wait);
return result;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 89c7485519cb..7eadb7fd8074 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -523,7 +523,9 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
sprintf(name, "pcm%i%c", pcm->device,
pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
- if ((entry = snd_info_create_card_entry(pcm->card, name, pcm->card->proc_root)) == NULL)
+ entry = snd_info_create_card_entry(pcm->card, name,
+ pcm->card->proc_root);
+ if (!entry)
return -ENOMEM;
entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
if (snd_info_register(entry) < 0) {
@@ -531,8 +533,8 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
return -ENOMEM;
}
pstr->proc_root = entry;
-
- if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) {
+ entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root);
+ if (entry) {
snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);
if (snd_info_register(entry) < 0) {
snd_info_free_entry(entry);
@@ -542,8 +544,9 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
pstr->proc_info_entry = entry;
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
- if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
- pstr->proc_root)) != NULL) {
+ entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
+ pstr->proc_root);
+ if (entry) {
entry->c.text.read = snd_pcm_xrun_debug_read;
entry->c.text.write = snd_pcm_xrun_debug_write;
entry->mode |= S_IWUSR;
@@ -580,7 +583,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
card = substream->pcm->card;
sprintf(name, "sub%i", substream->number);
- if ((entry = snd_info_create_card_entry(card, name, substream->pstr->proc_root)) == NULL)
+ entry = snd_info_create_card_entry(card, name,
+ substream->pstr->proc_root);
+ if (!entry)
return -ENOMEM;
entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
if (snd_info_register(entry) < 0) {
@@ -588,8 +593,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
return -ENOMEM;
}
substream->proc_root = entry;
-
- if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) {
+ entry = snd_info_create_card_entry(card, "info", substream->proc_root);
+ if (entry) {
snd_info_set_text_ops(entry, substream,
snd_pcm_substream_proc_info_read);
if (snd_info_register(entry) < 0) {
@@ -598,8 +603,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
}
}
substream->proc_info_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) {
+ entry = snd_info_create_card_entry(card, "hw_params",
+ substream->proc_root);
+ if (entry) {
snd_info_set_text_ops(entry, substream,
snd_pcm_substream_proc_hw_params_read);
if (snd_info_register(entry) < 0) {
@@ -608,8 +614,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
}
}
substream->proc_hw_params_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) {
+ entry = snd_info_create_card_entry(card, "sw_params",
+ substream->proc_root);
+ if (entry) {
snd_info_set_text_ops(entry, substream,
snd_pcm_substream_proc_sw_params_read);
if (snd_info_register(entry) < 0) {
@@ -618,8 +625,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
}
}
substream->proc_sw_params_entry = entry;
-
- if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) {
+ entry = snd_info_create_card_entry(card, "status",
+ substream->proc_root);
+ if (entry) {
snd_info_set_text_ops(entry, substream,
snd_pcm_substream_proc_status_read);
if (snd_info_register(entry) < 0) {
@@ -783,21 +791,27 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
INIT_LIST_HEAD(&pcm->list);
if (id)
strlcpy(pcm->id, id, sizeof(pcm->id));
- if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
- snd_pcm_free(pcm);
- return err;
- }
- if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count)) < 0) {
- snd_pcm_free(pcm);
- return err;
- }
- if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {
- snd_pcm_free(pcm);
- return err;
- }
+
+ err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ playback_count);
+ if (err < 0)
+ goto free_pcm;
+
+ err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count);
+ if (err < 0)
+ goto free_pcm;
+
+ err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops);
+ if (err < 0)
+ goto free_pcm;
+
if (rpcm)
*rpcm = pcm;
return 0;
+
+free_pcm:
+ snd_pcm_free(pcm);
+ return err;
}
/**
@@ -1224,7 +1238,8 @@ static void snd_pcm_proc_init(void)
{
struct snd_info_entry *entry;
- if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
+ entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL);
+ if (entry) {
snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
if (snd_info_register(entry) < 0) {
snd_info_free_entry(entry);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 10f537f4d735..3a1cc7b97e46 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -689,10 +689,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
case SNDRV_PCM_IOCTL_XRUN:
case SNDRV_PCM_IOCTL_LINK:
case SNDRV_PCM_IOCTL_UNLINK:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return snd_pcm_playback_ioctl1(file, substream, cmd, argp);
- else
- return snd_pcm_capture_ioctl1(file, substream, cmd, argp);
+ return snd_pcm_common_ioctl(file, substream, cmd, argp);
case SNDRV_PCM_IOCTL_HW_REFINE32:
return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
case SNDRV_PCM_IOCTL_HW_PARAMS32:
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index cf0433f80067..2fec2feac387 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1830,7 +1830,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
add_wait_queue(&to_check->sleep, &wait);
snd_pcm_stream_unlock_irq(substream);
up_read(&snd_pcm_link_rwsem);
- snd_power_unlock(card);
if (runtime->no_period_wakeup)
tout = MAX_SCHEDULE_TIMEOUT;
else {
@@ -1842,7 +1841,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
tout = msecs_to_jiffies(tout * 1000);
}
tout = schedule_timeout_interruptible(tout);
- snd_power_lock(card);
down_read(&snd_pcm_link_rwsem);
snd_pcm_stream_lock_irq(substream);
remove_wait_queue(&to_check->sleep, &wait);
@@ -2763,12 +2761,106 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
runtime->tstamp_type = arg;
return 0;
}
-
+
+static int snd_pcm_xferi_frames_ioctl(struct snd_pcm_substream *substream,
+ struct snd_xferi __user *_xferi)
+{
+ struct snd_xferi xferi;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ snd_pcm_sframes_t result;
+
+ if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ return -EBADFD;
+ if (put_user(0, &_xferi->result))
+ return -EFAULT;
+ if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
+ return -EFAULT;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
+ else
+ result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames);
+ __put_user(result, &_xferi->result);
+ return result < 0 ? result : 0;
+}
+
+static int snd_pcm_xfern_frames_ioctl(struct snd_pcm_substream *substream,
+ struct snd_xfern __user *_xfern)
+{
+ struct snd_xfern xfern;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ void *bufs;
+ snd_pcm_sframes_t result;
+
+ if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+ return -EBADFD;
+ if (runtime->channels > 128)
+ return -EINVAL;
+ if (put_user(0, &_xfern->result))
+ return -EFAULT;
+ if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
+ return -EFAULT;
+
+ bufs = memdup_user(xfern.bufs, sizeof(void *) * runtime->channels);
+ if (IS_ERR(bufs))
+ return PTR_ERR(bufs);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
+ else
+ result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
+ kfree(bufs);
+ __put_user(result, &_xfern->result);
+ return result < 0 ? result : 0;
+}
+
+static int snd_pcm_rewind_ioctl(struct snd_pcm_substream *substream,
+ snd_pcm_uframes_t __user *_frames)
+{
+ snd_pcm_uframes_t frames;
+ snd_pcm_sframes_t result;
+
+ if (get_user(frames, _frames))
+ return -EFAULT;
+ if (put_user(0, _frames))
+ return -EFAULT;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ result = snd_pcm_playback_rewind(substream, frames);
+ else
+ result = snd_pcm_capture_rewind(substream, frames);
+ __put_user(result, _frames);
+ return result < 0 ? result : 0;
+}
+
+static int snd_pcm_forward_ioctl(struct snd_pcm_substream *substream,
+ snd_pcm_uframes_t __user *_frames)
+{
+ snd_pcm_uframes_t frames;
+ snd_pcm_sframes_t result;
+
+ if (get_user(frames, _frames))
+ return -EFAULT;
+ if (put_user(0, _frames))
+ return -EFAULT;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ result = snd_pcm_playback_forward(substream, frames);
+ else
+ result = snd_pcm_capture_forward(substream, frames);
+ __put_user(result, _frames);
+ return result < 0 ? result : 0;
+}
+
static int snd_pcm_common_ioctl(struct file *file,
struct snd_pcm_substream *substream,
unsigned int cmd, void __user *arg)
{
struct snd_pcm_file *pcm_file = file->private_data;
+ int res;
+
+ if (PCM_RUNTIME_CHECK(substream))
+ return -ENXIO;
+
+ res = snd_power_wait(substream->pcm->card, SNDRV_CTL_POWER_D0);
+ if (res < 0)
+ return res;
switch (cmd) {
case SNDRV_PCM_IOCTL_PVERSION:
@@ -2841,202 +2933,23 @@ static int snd_pcm_common_ioctl(struct file *file,
return snd_pcm_action_lock_irq(&snd_pcm_action_pause,
substream,
(int)(unsigned long)arg);
- }
- pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd);
- return -ENOTTY;
-}
-
-static int snd_pcm_common_ioctl1(struct file *file,
- struct snd_pcm_substream *substream,
- unsigned int cmd, void __user *arg)
-{
- struct snd_card *card = substream->pcm->card;
- int res;
-
- snd_power_lock(card);
- res = snd_power_wait(card, SNDRV_CTL_POWER_D0);
- if (res >= 0)
- res = snd_pcm_common_ioctl(file, substream, cmd, arg);
- snd_power_unlock(card);
- return res;
-}
-
-static int snd_pcm_playback_ioctl1(struct file *file,
- struct snd_pcm_substream *substream,
- unsigned int cmd, void __user *arg)
-{
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
- return -EINVAL;
- switch (cmd) {
case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
- {
- struct snd_xferi xferi;
- struct snd_xferi __user *_xferi = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (put_user(0, &_xferi->result))
- return -EFAULT;
- if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
- return -EFAULT;
- result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
- __put_user(result, &_xferi->result);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
- {
- struct snd_xfern xfern;
- struct snd_xfern __user *_xfern = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- void __user **bufs;
- snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (runtime->channels > 128)
- return -EINVAL;
- if (put_user(0, &_xfern->result))
- return -EFAULT;
- if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
- return -EFAULT;
-
- bufs = memdup_user(xfern.bufs,
- sizeof(void *) * runtime->channels);
- if (IS_ERR(bufs))
- return PTR_ERR(bufs);
- result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
- kfree(bufs);
- __put_user(result, &_xfern->result);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_REWIND:
- {
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t __user *_frames = arg;
- snd_pcm_sframes_t result;
- if (get_user(frames, _frames))
- return -EFAULT;
- if (put_user(0, _frames))
- return -EFAULT;
- result = snd_pcm_playback_rewind(substream, frames);
- __put_user(result, _frames);
- return result < 0 ? result : 0;
- }
- case SNDRV_PCM_IOCTL_FORWARD:
- {
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t __user *_frames = arg;
- snd_pcm_sframes_t result;
- if (get_user(frames, _frames))
- return -EFAULT;
- if (put_user(0, _frames))
- return -EFAULT;
- result = snd_pcm_playback_forward(substream, frames);
- __put_user(result, _frames);
- return result < 0 ? result : 0;
- }
- }
- return snd_pcm_common_ioctl1(file, substream, cmd, arg);
-}
-
-static int snd_pcm_capture_ioctl1(struct file *file,
- struct snd_pcm_substream *substream,
- unsigned int cmd, void __user *arg)
-{
- if (PCM_RUNTIME_CHECK(substream))
- return -ENXIO;
- if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE))
- return -EINVAL;
- switch (cmd) {
case SNDRV_PCM_IOCTL_READI_FRAMES:
- {
- struct snd_xferi xferi;
- struct snd_xferi __user *_xferi = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (put_user(0, &_xferi->result))
- return -EFAULT;
- if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
- return -EFAULT;
- result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames);
- __put_user(result, &_xferi->result);
- return result < 0 ? result : 0;
- }
+ return snd_pcm_xferi_frames_ioctl(substream, arg);
+ case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
case SNDRV_PCM_IOCTL_READN_FRAMES:
- {
- struct snd_xfern xfern;
- struct snd_xfern __user *_xfern = arg;
- struct snd_pcm_runtime *runtime = substream->runtime;
- void *bufs;
- snd_pcm_sframes_t result;
- if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (runtime->channels > 128)
- return -EINVAL;
- if (put_user(0, &_xfern->result))
- return -EFAULT;
- if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
- return -EFAULT;
-
- bufs = memdup_user(xfern.bufs,
- sizeof(void *) * runtime->channels);
- if (IS_ERR(bufs))
- return PTR_ERR(bufs);
- result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
- kfree(bufs);
- __put_user(result, &_xfern->result);
- return result < 0 ? result : 0;
- }
+ return snd_pcm_xfern_frames_ioctl(substream, arg);
case SNDRV_PCM_IOCTL_REWIND:
- {
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t __user *_frames = arg;
- snd_pcm_sframes_t result;
- if (get_user(frames, _frames))
- return -EFAULT;
- if (put_user(0, _frames))
- return -EFAULT;
- result = snd_pcm_capture_rewind(substream, frames);
- __put_user(result, _frames);
- return result < 0 ? result : 0;
- }
+ return snd_pcm_rewind_ioctl(substream, arg);
case SNDRV_PCM_IOCTL_FORWARD:
- {
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t __user *_frames = arg;
- snd_pcm_sframes_t result;
- if (get_user(frames, _frames))
- return -EFAULT;
- if (put_user(0, _frames))
- return -EFAULT;
- result = snd_pcm_capture_forward(substream, frames);
- __put_user(result, _frames);
- return result < 0 ? result : 0;
+ return snd_pcm_forward_ioctl(substream, arg);
}
- }
- return snd_pcm_common_ioctl1(file, substream, cmd, arg);
-}
-
-static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct snd_pcm_file *pcm_file;
-
- pcm_file = file->private_data;
-
- if (((cmd >> 8) & 0xff) != 'A')
- return -ENOTTY;
-
- return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
- (void __user *)arg);
+ pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd);
+ return -ENOTTY;
}
-static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+static long snd_pcm_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
struct snd_pcm_file *pcm_file;
@@ -3045,8 +2958,8 @@ static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
if (((cmd >> 8) & 0xff) != 'A')
return -ENOTTY;
- return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
- (void __user *)arg);
+ return snd_pcm_common_ioctl(file, pcm_file->substream, cmd,
+ (void __user *)arg);
}
/**
@@ -3064,7 +2977,6 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
{
snd_pcm_uframes_t *frames = arg;
snd_pcm_sframes_t result;
- int err;
switch (cmd) {
case SNDRV_PCM_IOCTL_FORWARD:
@@ -3084,10 +2996,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
case SNDRV_PCM_IOCTL_START:
return snd_pcm_start_lock_irq(substream);
case SNDRV_PCM_IOCTL_DRAIN:
- snd_power_lock(substream->pcm->card);
- err = snd_pcm_drain(substream, NULL);
- snd_power_unlock(substream->pcm->card);
- return err;
+ return snd_pcm_drain(substream, NULL);
case SNDRV_PCM_IOCTL_DROP:
return snd_pcm_drop(substream);
case SNDRV_PCM_IOCTL_DELAY:
@@ -3791,7 +3700,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
.release = snd_pcm_release,
.llseek = no_llseek,
.poll = snd_pcm_playback_poll,
- .unlocked_ioctl = snd_pcm_playback_ioctl,
+ .unlocked_ioctl = snd_pcm_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
@@ -3805,7 +3714,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
.release = snd_pcm_release,
.llseek = no_llseek,
.poll = snd_pcm_capture_poll,
- .unlocked_ioctl = snd_pcm_capture_ioctl,
+ .unlocked_ioctl = snd_pcm_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
diff --git a/sound/core/timer.c b/sound/core/timer.c
index a9b9a277e00c..6cdd04a45962 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -393,7 +393,8 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
if (timeri == NULL)
return 0;
- if ((timer = timeri->timer) != NULL) {
+ timer = timeri->timer;
+ if (timer) {
if (timer->hw.c_resolution)
return timer->hw.c_resolution(timer);
return timer->hw.resolution;
@@ -2096,8 +2097,7 @@ static int __init alsa_timer_init(void)
err = snd_timer_register_system();
if (err < 0) {
pr_err("ALSA: unable to register system timer (%i)\n", err);
- put_device(&timer_dev);
- return err;
+ goto put_timer;
}
err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
@@ -2105,12 +2105,15 @@ static int __init alsa_timer_init(void)
if (err < 0) {
pr_err("ALSA: unable to register timer device (%i)\n", err);
snd_timer_free_all();
- put_device(&timer_dev);
- return err;
+ goto put_timer;
}
snd_timer_proc_init();
return 0;
+
+put_timer:
+ put_device(&timer_dev);
+ return err;
}
static void __exit alsa_timer_exit(void)
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 54f348a4fb78..135adb17703c 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -561,7 +561,7 @@ static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
return bytes_to_frames(runtime, pos);
}
-static struct snd_pcm_hardware loopback_pcm_hardware =
+static const struct snd_pcm_hardware loopback_pcm_hardware =
{
.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE |
@@ -750,7 +750,7 @@ static int loopback_close(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_ops loopback_playback_ops = {
+static const struct snd_pcm_ops loopback_playback_ops = {
.open = loopback_open,
.close = loopback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -763,7 +763,7 @@ static struct snd_pcm_ops loopback_playback_ops = {
.mmap = snd_pcm_lib_mmap_vmalloc,
};
-static struct snd_pcm_ops loopback_capture_ops = {
+static const struct snd_pcm_ops loopback_capture_ops = {
.open = loopback_open,
.close = loopback_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index dd5ed037adf2..c0939a0164a6 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -520,7 +520,7 @@ static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
return get_dummy_ops(substream)->pointer(substream);
}
-static struct snd_pcm_hardware dummy_pcm_hardware = {
+static const struct snd_pcm_hardware dummy_pcm_hardware = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME |
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index bdcb5721393b..18fd12996cf7 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -373,7 +373,7 @@ struct snd_ml403_ac97cr {
struct snd_pcm_indirect2 capture_ind2_rec;
};
-static struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
+static const struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -392,7 +392,7 @@ static struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_ml403_ac97cr_capture = {
+static const struct snd_pcm_hardware snd_ml403_ac97cr_capture = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -759,7 +759,7 @@ static int snd_ml403_ac97cr_capture_close(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {
+static const struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {
.open = snd_ml403_ac97cr_playback_open,
.close = snd_ml403_ac97cr_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -770,7 +770,7 @@ static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {
.pointer = snd_ml403_ac97cr_pcm_pointer,
};
-static struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = {
+static const struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = {
.open = snd_ml403_ac97cr_capture_open,
.close = snd_ml403_ac97cr_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 9b86e00d7d95..b6715764cd1c 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -148,7 +148,7 @@ static struct platform_driver snd_mpu401_driver = {
#define IO_EXTENT 2
-static struct pnp_device_id snd_mpu401_pnpids[] = {
+static const struct pnp_device_id snd_mpu401_pnpids[] = {
{ .id = "PNPb006" },
{ .id = "" }
};
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 3a7c317ae012..b997222274bd 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -136,7 +136,7 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id)
{
struct snd_mpu401 *mpu = dev_id;
- if (mpu == NULL)
+ if (!mpu)
return IRQ_NONE;
_snd_mpu401_uart_interrupt(mpu);
return IRQ_HANDLED;
@@ -157,7 +157,7 @@ irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id)
{
struct snd_mpu401 *mpu = dev_id;
- if (mpu == NULL)
+ if (!mpu)
return IRQ_NONE;
uart_interrupt_tx(mpu);
return IRQ_HANDLED;
@@ -544,10 +544,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
out_enable, in_enable, &rmidi)) < 0)
return err;
mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
- if (mpu == NULL) {
- snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n");
- snd_device_free(card, rmidi);
- return -ENOMEM;
+ if (!mpu) {
+ err = -ENOMEM;
+ goto free_device;
}
rmidi->private_data = mpu;
rmidi->private_free = snd_mpu401_uart_free;
@@ -559,12 +558,12 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
if (! (info_flags & MPU401_INFO_INTEGRATED)) {
int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
mpu->res = request_region(port, res_size, "MPU401 UART");
- if (mpu->res == NULL) {
+ if (!mpu->res) {
snd_printk(KERN_ERR "mpu401_uart: "
"unable to grab port 0x%lx size %d\n",
port, res_size);
- snd_device_free(card, rmidi);
- return -EBUSY;
+ err = -EBUSY;
+ goto free_device;
}
}
if (info_flags & MPU401_INFO_MMIO) {
@@ -584,8 +583,8 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
"MPU401 UART", (void *) mpu)) {
snd_printk(KERN_ERR "mpu401_uart: "
"unable to grab IRQ %d\n", irq);
- snd_device_free(card, rmidi);
- return -EBUSY;
+ err = -EBUSY;
+ goto free_device;
}
}
if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK))
@@ -613,6 +612,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
if (rrawmidi)
*rrawmidi = rmidi;
return 0;
+free_device:
+ snd_device_free(card, rmidi);
+ return err;
}
EXPORT_SYMBOL(snd_mpu401_uart_new);
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index d5e5b4657b4b..588963d6be28 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -355,10 +355,8 @@ int snd_opl3_new(struct snd_card *card,
*ropl3 = NULL;
opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
- if (opl3 == NULL) {
- snd_printk(KERN_ERR "opl3: cannot allocate\n");
+ if (!opl3)
return -ENOMEM;
- }
opl3->card = card;
opl3->hardware = hardware;
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 7821b07415a7..13c0a7e1bc2b 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -131,8 +131,8 @@ static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) {
printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice);
for (i = 0; i < opl3->max_voices; i++)
- printk("%c", *(str + opl3->voices[i].state + 1));
- printk("\n");
+ printk(KERN_CONT "%c", *(str + opl3->voices[i].state + 1));
+ printk(KERN_CONT "\n");
}
#endif
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 72e2d0012084..0dd3f46eb03e 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -108,22 +108,17 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev)
return err;
err = snd_pcsp_create(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
+ if (err < 0)
+ goto free_card;
+
if (!nopcm) {
err = snd_pcsp_new_pcm(&pcsp_chip);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
+ if (err < 0)
+ goto free_card;
}
err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
+ if (err < 0)
+ goto free_card;
strcpy(card->driver, "PC-Speaker");
strcpy(card->shortname, "pcsp");
@@ -131,12 +126,14 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev)
pcsp_chip.port);
err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
+ if (err < 0)
+ goto free_card;
return 0;
+
+free_card:
+ snd_card_free(card);
+ return err;
}
static int alsa_card_pcsp_init(struct device *dev)
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index 44b3632f6940..2f5a35f38ce1 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -285,7 +285,7 @@ static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream
return bytes_to_frames(substream->runtime, pos);
}
-static struct snd_pcm_hardware snd_pcsp_playback = {
+static const struct snd_pcm_hardware snd_pcsp_playback = {
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_HALF_DUPLEX |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index f684fffd1397..121357397a6d 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -256,8 +256,8 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
if (rmh->LgCmd > 1) {
printk(KERN_DEBUG " ");
for (i = 1; i < rmh->LgCmd; i++)
- printk("0x%06x ", rmh->Cmd[i]);
- printk("\n");
+ printk(KERN_CONT "0x%06x ", rmh->Cmd[i]);
+ printk(KERN_CONT "\n");
}
#endif
/* Check bit M is set according to length of the command */
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index d318a33b6cfb..380a028469c4 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -500,7 +500,7 @@ static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe)
* playback hw information
*/
-static struct snd_pcm_hardware vx_pcm_playback_hw = {
+static const struct snd_pcm_hardware vx_pcm_playback_hw = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
/*SNDRV_PCM_INFO_RESUME*/),
@@ -891,7 +891,7 @@ static const struct snd_pcm_ops vx_pcm_playback_ops = {
* playback hw information
*/
-static struct snd_pcm_hardware vx_pcm_capture_hw = {
+static const struct snd_pcm_hardware vx_pcm_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
/*SNDRV_PCM_INFO_RESUME*/),
diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h
index 17678d6ab5a2..df1b1e94c43c 100644
--- a/sound/firewire/bebob/bebob.h
+++ b/sound/firewire/bebob/bebob.h
@@ -58,7 +58,7 @@ enum snd_bebob_clock_type {
struct snd_bebob_clock_spec {
unsigned int num;
const char *const *labels;
- enum snd_bebob_clock_type *types;
+ const enum snd_bebob_clock_type *types;
int (*get)(struct snd_bebob *bebob, unsigned int *id);
};
struct snd_bebob_rate_spec {
diff --git a/sound/firewire/bebob/bebob_focusrite.c b/sound/firewire/bebob/bebob_focusrite.c
index f11090057949..52b8b61ecddd 100644
--- a/sound/firewire/bebob/bebob_focusrite.c
+++ b/sound/firewire/bebob/bebob_focusrite.c
@@ -103,12 +103,12 @@ saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value)
&data, sizeof(__be32), 0);
}
-static enum snd_bebob_clock_type saffirepro_10_clk_src_types[] = {
+static const enum snd_bebob_clock_type saffirepro_10_clk_src_types[] = {
SND_BEBOB_CLOCK_TYPE_INTERNAL,
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */
};
-static enum snd_bebob_clock_type saffirepro_26_clk_src_types[] = {
+static const enum snd_bebob_clock_type saffirepro_26_clk_src_types[] = {
SND_BEBOB_CLOCK_TYPE_INTERNAL,
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* ADAT1 */
@@ -201,7 +201,7 @@ end:
}
const struct snd_bebob_spec saffire_le_spec;
-static enum snd_bebob_clock_type saffire_both_clk_src_types[] = {
+static const enum snd_bebob_clock_type saffire_both_clk_src_types[] = {
SND_BEBOB_CLOCK_TYPE_INTERNAL,
SND_BEBOB_CLOCK_TYPE_EXTERNAL,
};
diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c
index d10208f92edf..bd55620c6a47 100644
--- a/sound/firewire/bebob/bebob_maudio.c
+++ b/sound/firewire/bebob/bebob_maudio.c
@@ -340,7 +340,7 @@ end:
}
/* Clock source control for special firmware */
-static enum snd_bebob_clock_type special_clk_types[] = {
+static const enum snd_bebob_clock_type special_clk_types[] = {
SND_BEBOB_CLOCK_TYPE_INTERNAL, /* With digital mute */
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* SPDIF/ADAT */
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */
diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c
index 2fdaf93e7a8d..9770c2127a7a 100644
--- a/sound/firewire/bebob/bebob_terratec.c
+++ b/sound/firewire/bebob/bebob_terratec.c
@@ -8,7 +8,7 @@
#include "./bebob.h"
-static enum snd_bebob_clock_type phase88_rack_clk_src_types[] = {
+static const enum snd_bebob_clock_type phase88_rack_clk_src_types[] = {
SND_BEBOB_CLOCK_TYPE_INTERNAL,
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */
diff --git a/sound/firewire/bebob/bebob_yamaha_terratec.c b/sound/firewire/bebob/bebob_yamaha_terratec.c
index a6be3e7138e0..8bd78fef3516 100644
--- a/sound/firewire/bebob/bebob_yamaha_terratec.c
+++ b/sound/firewire/bebob/bebob_yamaha_terratec.c
@@ -31,7 +31,7 @@
* Yamaha GO 44 and GO 46. Yamaha and Terratec had cooperated for these models.
*/
-static enum snd_bebob_clock_type clk_src_types[] = {
+static const enum snd_bebob_clock_type clk_src_types[] = {
SND_BEBOB_CLOCK_TYPE_INTERNAL,
SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */
};
diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c
index 25e9f77275c4..4ddb4cdd054b 100644
--- a/sound/firewire/dice/dice.c
+++ b/sound/firewire/dice/dice.c
@@ -26,7 +26,7 @@ MODULE_LICENSE("GPL v2");
*/
static bool force_two_pcm_support(struct fw_unit *unit)
{
- const char *const models[] = {
+ static const char *const models[] = {
/* TC Electronic models. */
"StudioKonnekt48",
/* Focusrite models. */
diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c
index d12a0e3a4219..e3c16308363d 100644
--- a/sound/firewire/fireface/ff-pcm.c
+++ b/sound/firewire/fireface/ff-pcm.c
@@ -138,16 +138,12 @@ static int pcm_open(struct snd_pcm_substream *substream)
return err;
err = pcm_init_hw_params(ff, substream);
- if (err < 0) {
- snd_ff_stream_lock_release(ff);
- return err;
- }
+ if (err < 0)
+ goto release_lock;
err = ff->spec->protocol->get_clock(ff, &rate, &src);
- if (err < 0) {
- snd_ff_stream_lock_release(ff);
- return err;
- }
+ if (err < 0)
+ goto release_lock;
if (src != SND_FF_CLOCK_SRC_INTERNAL) {
for (i = 0; i < CIP_SFC_COUNT; ++i) {
@@ -159,8 +155,8 @@ static int pcm_open(struct snd_pcm_substream *substream)
* streaming engine can't support.
*/
if (i >= CIP_SFC_COUNT) {
- snd_ff_stream_lock_release(ff);
- return -EIO;
+ err = -EIO;
+ goto release_lock;
}
substream->runtime->hw.rate_min = rate;
@@ -177,6 +173,10 @@ static int pcm_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
return 0;
+
+release_lock:
+ snd_ff_stream_lock_release(ff);
+ return err;
}
static int pcm_close(struct snd_pcm_substream *substream)
diff --git a/sound/firewire/fireface/ff-protocol-ff400.c b/sound/firewire/fireface/ff-protocol-ff400.c
index fcec6de80eeb..12aa15df435d 100644
--- a/sound/firewire/fireface/ff-protocol-ff400.c
+++ b/sound/firewire/fireface/ff-protocol-ff400.c
@@ -356,7 +356,7 @@ static void ff400_dump_clock_config(struct snd_ff *ff,
snd_iprintf(buffer, "Sync to clock source: %s\n", src);
}
-struct snd_ff_protocol snd_ff_protocol_ff400 = {
+const struct snd_ff_protocol snd_ff_protocol_ff400 = {
.get_clock = ff400_get_clock,
.begin_session = ff400_begin_session,
.finish_session = ff400_finish_session,
diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c
index eee7c8eac7a6..4974bc7980e9 100644
--- a/sound/firewire/fireface/ff.c
+++ b/sound/firewire/fireface/ff.c
@@ -157,7 +157,7 @@ static void snd_ff_remove(struct fw_unit *unit)
}
}
-static struct snd_ff_spec spec_ff400 = {
+static const struct snd_ff_spec spec_ff400 = {
.name = "Fireface400",
.pcm_capture_channels = {18, 14, 10},
.pcm_playback_channels = {18, 14, 10},
diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h
index 3cb812a50030..64df44beb950 100644
--- a/sound/firewire/fireface/ff.h
+++ b/sound/firewire/fireface/ff.h
@@ -47,7 +47,7 @@ struct snd_ff_spec {
unsigned int midi_in_ports;
unsigned int midi_out_ports;
- struct snd_ff_protocol *protocol;
+ const struct snd_ff_protocol *protocol;
};
struct snd_ff {
@@ -112,7 +112,7 @@ struct snd_ff_protocol {
u64 midi_rx_port_1_reg;
};
-extern struct snd_ff_protocol snd_ff_protocol_ff400;
+extern const struct snd_ff_protocol snd_ff_protocol_ff400;
int snd_ff_transaction_register(struct snd_ff *ff);
int snd_ff_transaction_reregister(struct snd_ff *ff);
diff --git a/sound/firewire/fireworks/fireworks_proc.c b/sound/firewire/fireworks/fireworks_proc.c
index beb0a0ffee57..9c21f31b8b21 100644
--- a/sound/firewire/fireworks/fireworks_proc.c
+++ b/sound/firewire/fireworks/fireworks_proc.c
@@ -12,7 +12,7 @@
static inline const char*
get_phys_name(struct snd_efw_phys_grp *grp, bool input)
{
- const char *const ch_type[] = {
+ static const char *const ch_type[] = {
"Analog", "S/PDIF", "ADAT", "S/PDIF or ADAT", "Mirroring",
"Headphones", "I2S", "Guitar", "Pirzo Guitar", "Guitar String",
};
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
index 48d6dca471c6..5826aa8362f1 100644
--- a/sound/firewire/isight.c
+++ b/sound/firewire/isight.c
@@ -444,7 +444,7 @@ static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream)
static int isight_create_pcm(struct isight *isight)
{
- static struct snd_pcm_ops ops = {
+ static const struct snd_pcm_ops ops = {
.open = isight_open,
.close = isight_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/firewire/motu/motu-midi.c b/sound/firewire/motu/motu-midi.c
index e3acfcc53f4e..e55cab6d79c7 100644
--- a/sound/firewire/motu/motu-midi.c
+++ b/sound/firewire/motu/motu-midi.c
@@ -128,12 +128,12 @@ static void set_midi_substream_names(struct snd_motu *motu,
int snd_motu_create_midi_devices(struct snd_motu *motu)
{
- static struct snd_rawmidi_ops capture_ops = {
+ static const struct snd_rawmidi_ops capture_ops = {
.open = midi_capture_open,
.close = midi_capture_close,
.trigger = midi_capture_trigger,
};
- static struct snd_rawmidi_ops playback_ops = {
+ static const struct snd_rawmidi_ops playback_ops = {
.open = midi_playback_open,
.close = midi_playback_close,
.trigger = midi_playback_trigger,
diff --git a/sound/firewire/motu/motu-pcm.c b/sound/firewire/motu/motu-pcm.c
index a2b50df70874..4330220890e8 100644
--- a/sound/firewire/motu/motu-pcm.c
+++ b/sound/firewire/motu/motu-pcm.c
@@ -145,7 +145,7 @@ static int pcm_open(struct snd_pcm_substream *substream)
mutex_lock(&motu->mutex);
- err = protocol->cache_packet_formats(motu);
+ err = snd_motu_stream_cache_packet_formats(motu);
if (err < 0)
goto err_locked;
@@ -352,7 +352,7 @@ static int playback_ack(struct snd_pcm_substream *substream)
int snd_motu_create_pcm_devices(struct snd_motu *motu)
{
- static struct snd_pcm_ops capture_ops = {
+ static const struct snd_pcm_ops capture_ops = {
.open = pcm_open,
.close = pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -365,7 +365,7 @@ int snd_motu_create_pcm_devices(struct snd_motu *motu)
.page = snd_pcm_lib_get_vmalloc_page,
.mmap = snd_pcm_lib_mmap_vmalloc,
};
- static struct snd_pcm_ops playback_ops = {
+ static const struct snd_pcm_ops playback_ops = {
.open = pcm_open,
.close = pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c
index 05b5d287c2f3..525b746330be 100644
--- a/sound/firewire/motu/motu-protocol-v2.c
+++ b/sound/firewire/motu/motu-protocol-v2.c
@@ -217,12 +217,7 @@ static int v2_cache_packet_formats(struct snd_motu *motu)
calculate_differed_part(&motu->rx_packet_formats, motu->spec->flags,
data, V2_OPT_OUT_IFACE_MASK, V2_OPT_OUT_IFACE_SHIFT);
- motu->tx_packet_formats.midi_flag_offset = 4;
- motu->tx_packet_formats.midi_byte_offset = 6;
motu->tx_packet_formats.pcm_byte_offset = 10;
-
- motu->rx_packet_formats.midi_flag_offset = 4;
- motu->rx_packet_formats.midi_byte_offset = 6;
motu->rx_packet_formats.pcm_byte_offset = 10;
return 0;
diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c
index ddb647254ed2..c7cd9864dc4d 100644
--- a/sound/firewire/motu/motu-protocol-v3.c
+++ b/sound/firewire/motu/motu-protocol-v3.c
@@ -291,12 +291,7 @@ static int v3_cache_packet_formats(struct snd_motu *motu)
V3_ENABLE_OPT_OUT_IFACE_A, V3_NO_ADAT_OPT_OUT_IFACE_A,
V3_ENABLE_OPT_OUT_IFACE_B, V3_NO_ADAT_OPT_OUT_IFACE_B);
- motu->tx_packet_formats.midi_flag_offset = 8;
- motu->tx_packet_formats.midi_byte_offset = 7;
motu->tx_packet_formats.pcm_byte_offset = 10;
-
- motu->rx_packet_formats.midi_flag_offset = 8;
- motu->rx_packet_formats.midi_byte_offset = 7;
motu->rx_packet_formats.pcm_byte_offset = 10;
return 0;
diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c
index bd458029099e..dc5541c8b359 100644
--- a/sound/firewire/motu/motu-stream.c
+++ b/sound/firewire/motu/motu-stream.c
@@ -33,7 +33,8 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate)
u32 data;
int err;
- if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI)
+ if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) ||
+ (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q))
midi_ports = 1;
/* Set packet formation to our packet streaming engine. */
@@ -42,6 +43,12 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate)
if (err < 0)
return err;
+ if ((motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) ||
+ (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q))
+ midi_ports = 1;
+ else
+ midi_ports = 0;
+
err = amdtp_motu_set_parameters(&motu->tx_stream, rate, midi_ports,
&motu->tx_packet_formats);
if (err < 0)
@@ -141,6 +148,33 @@ static void stop_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream)
fw_iso_resources_free(resources);
}
+int snd_motu_stream_cache_packet_formats(struct snd_motu *motu)
+{
+ int err;
+
+ err = motu->spec->protocol->cache_packet_formats(motu);
+ if (err < 0)
+ return err;
+
+ if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) {
+ motu->tx_packet_formats.midi_flag_offset = 4;
+ motu->tx_packet_formats.midi_byte_offset = 6;
+ } else if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q) {
+ motu->tx_packet_formats.midi_flag_offset = 8;
+ motu->tx_packet_formats.midi_byte_offset = 7;
+ }
+
+ if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) {
+ motu->rx_packet_formats.midi_flag_offset = 4;
+ motu->rx_packet_formats.midi_byte_offset = 6;
+ } else if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) {
+ motu->rx_packet_formats.midi_flag_offset = 8;
+ motu->rx_packet_formats.midi_byte_offset = 7;
+ }
+
+ return 0;
+}
+
static int ensure_packet_formats(struct snd_motu *motu)
{
__be32 reg;
@@ -184,7 +218,7 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate)
stop_both_streams(motu);
}
- err = protocol->cache_packet_formats(motu);
+ err = snd_motu_stream_cache_packet_formats(motu);
if (err < 0)
return err;
diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c
index 59a270406353..0d6b526105ab 100644
--- a/sound/firewire/motu/motu.c
+++ b/sound/firewire/motu/motu.c
@@ -103,7 +103,10 @@ static void do_registration(struct work_struct *work)
if (err < 0)
goto error;
- if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) {
+ if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) ||
+ (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) ||
+ (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) ||
+ (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) {
err = snd_motu_create_midi_devices(motu);
if (err < 0)
goto error;
@@ -191,20 +194,21 @@ static void motu_bus_update(struct fw_unit *unit)
snd_motu_transaction_reregister(motu);
}
-static struct snd_motu_spec motu_828mk2 = {
+static const struct snd_motu_spec motu_828mk2 = {
.name = "828mk2",
.protocol = &snd_motu_protocol_v2,
.flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
SND_MOTU_SPEC_TX_MICINST_CHUNK |
SND_MOTU_SPEC_TX_RETURN_CHUNK |
SND_MOTU_SPEC_HAS_OPT_IFACE_A |
- SND_MOTU_SPEC_HAS_MIDI,
+ SND_MOTU_SPEC_RX_MIDI_2ND_Q |
+ SND_MOTU_SPEC_TX_MIDI_2ND_Q,
.analog_in_ports = 8,
.analog_out_ports = 8,
};
-static struct snd_motu_spec motu_828mk3 = {
+static const struct snd_motu_spec motu_828mk3 = {
.name = "828mk3",
.protocol = &snd_motu_protocol_v3,
.flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
@@ -214,12 +218,25 @@ static struct snd_motu_spec motu_828mk3 = {
SND_MOTU_SPEC_TX_REVERB_CHUNK |
SND_MOTU_SPEC_HAS_OPT_IFACE_A |
SND_MOTU_SPEC_HAS_OPT_IFACE_B |
- SND_MOTU_SPEC_HAS_MIDI,
+ SND_MOTU_SPEC_RX_MIDI_3RD_Q |
+ SND_MOTU_SPEC_TX_MIDI_3RD_Q,
.analog_in_ports = 8,
.analog_out_ports = 8,
};
+static const struct snd_motu_spec motu_audio_express = {
+ .name = "AudioExpress",
+ .protocol = &snd_motu_protocol_v3,
+ .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 |
+ SND_MOTU_SPEC_TX_MICINST_CHUNK |
+ SND_MOTU_SPEC_TX_RETURN_CHUNK |
+ SND_MOTU_SPEC_RX_MIDI_2ND_Q |
+ SND_MOTU_SPEC_TX_MIDI_3RD_Q,
+ .analog_in_ports = 2,
+ .analog_out_ports = 4,
+};
+
#define SND_MOTU_DEV_ENTRY(model, data) \
{ \
.match_flags = IEEE1394_MATCH_VENDOR_ID | \
@@ -235,6 +252,7 @@ static const struct ieee1394_device_id motu_id_table[] = {
SND_MOTU_DEV_ENTRY(0x101800, &motu_828mk2),
SND_MOTU_DEV_ENTRY(0x106800, &motu_828mk3), /* FireWire only. */
SND_MOTU_DEV_ENTRY(0x100800, &motu_828mk3), /* Hybrid. */
+ SND_MOTU_DEV_ENTRY(0x104800, &motu_audio_express),
{ }
};
MODULE_DEVICE_TABLE(ieee1394, motu_id_table);
diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h
index 8d6a4a3af9cc..4b23cf337c4b 100644
--- a/sound/firewire/motu/motu.h
+++ b/sound/firewire/motu/motu.h
@@ -82,7 +82,10 @@ enum snd_motu_spec_flags {
SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020,
SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040,
SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080,
- SND_MOTU_SPEC_HAS_MIDI = 0x0100,
+ SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0100,
+ SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0200,
+ SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0400,
+ SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0800,
};
#define SND_MOTU_CLOCK_RATE_COUNT 6
@@ -146,6 +149,7 @@ void snd_motu_transaction_unregister(struct snd_motu *motu);
int snd_motu_stream_init_duplex(struct snd_motu *motu);
void snd_motu_stream_destroy_duplex(struct snd_motu *motu);
+int snd_motu_stream_cache_packet_formats(struct snd_motu *motu);
int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate);
void snd_motu_stream_stop_duplex(struct snd_motu *motu);
int snd_motu_stream_lock_try(struct snd_motu *motu);
diff --git a/sound/firewire/oxfw/oxfw-scs1x.c b/sound/firewire/oxfw/oxfw-scs1x.c
index 93209ebd9121..02d595665898 100644
--- a/sound/firewire/oxfw/oxfw-scs1x.c
+++ b/sound/firewire/oxfw/oxfw-scs1x.c
@@ -297,12 +297,6 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *stream, int up)
}
}
-static const struct snd_rawmidi_ops midi_capture_ops = {
- .open = midi_capture_open,
- .close = midi_capture_close,
- .trigger = midi_capture_trigger,
-};
-
static int midi_playback_open(struct snd_rawmidi_substream *stream)
{
return 0;
@@ -363,6 +357,11 @@ void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw)
int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw)
{
+ static const struct snd_rawmidi_ops midi_capture_ops = {
+ .open = midi_capture_open,
+ .close = midi_capture_close,
+ .trigger = midi_capture_trigger,
+ };
static const struct snd_rawmidi_ops midi_playback_ops = {
.open = midi_playback_open,
.close = midi_playback_close,
diff --git a/sound/firewire/tascam/tascam.c b/sound/firewire/tascam/tascam.c
index 9dc93a7eb9da..44ad41fb7374 100644
--- a/sound/firewire/tascam/tascam.c
+++ b/sound/firewire/tascam/tascam.c
@@ -12,7 +12,7 @@ MODULE_DESCRIPTION("TASCAM FireWire series Driver");
MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");
MODULE_LICENSE("GPL v2");
-static struct snd_tscm_spec model_specs[] = {
+static const struct snd_tscm_spec model_specs[] = {
{
.name = "FW-1884",
.has_adat = true,
diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
index 0659bf389489..038a180d3f81 100644
--- a/sound/hda/hdac_i915.c
+++ b/sound/hda/hdac_i915.c
@@ -336,7 +336,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier);
/* check whether intel graphics is present */
static bool i915_gfx_present(void)
{
- static struct pci_device_id ids[] = {
+ static const struct pci_device_id ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
.class = PCI_BASE_CLASS_DISPLAY << 16,
.class_mask = 0xff << 16 },
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 769226515f0d..4be6c1245820 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -63,7 +63,7 @@ MODULE_PARM_DESC(enable, "Enable ad1816a based soundcard.");
module_param_array(clockfreq, int, NULL, 0444);
MODULE_PARM_DESC(clockfreq, "Clock frequency for ad1816a driver (default = 0).");
-static struct pnp_card_device_id snd_ad1816a_pnpids[] = {
+static const struct pnp_card_device_id snd_ad1816a_pnpids[] = {
/* Analog Devices AD1815 */
{ .id = "ADS7150", .devs = { { .id = "ADS7150" }, { .id = "ADS7151" } } },
/* Analog Device AD1816? */
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 5c815f5fb044..923201414469 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -339,7 +339,7 @@ static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id)
}
-static struct snd_pcm_hardware snd_ad1816a_playback = {
+static const struct snd_pcm_hardware snd_ad1816a_playback = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
.formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
@@ -358,7 +358,7 @@ static struct snd_pcm_hardware snd_ad1816a_playback = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_ad1816a_capture = {
+static const struct snd_pcm_hardware snd_ad1816a_capture = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
.formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
@@ -653,7 +653,7 @@ int snd_ad1816a_create(struct snd_card *card,
return 0;
}
-static struct snd_pcm_ops snd_ad1816a_playback_ops = {
+static const struct snd_pcm_ops snd_ad1816a_playback_ops = {
.open = snd_ad1816a_playback_open,
.close = snd_ad1816a_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -664,7 +664,7 @@ static struct snd_pcm_ops snd_ad1816a_playback_ops = {
.pointer = snd_ad1816a_playback_pointer,
};
-static struct snd_pcm_ops snd_ad1816a_capture_ops = {
+static const struct snd_pcm_ops snd_ad1816a_capture_ops = {
.open = snd_ad1816a_capture_open,
.close = snd_ad1816a_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index e739b1c85c25..7c8e92f62f3b 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -110,13 +110,17 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n)
if (error < 0)
goto out;
- strcpy(card->driver, "AD1848");
- strcpy(card->shortname, chip->pcm->name);
-
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- chip->pcm->name, chip->port, irq[n], dma1[n]);
- if (thinkpad[n])
- strcat(card->longname, " [Thinkpad]");
+ strlcpy(card->driver, "AD1848", sizeof(card->driver));
+ strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname));
+
+ if (!thinkpad[n])
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx, irq %d, dma %d",
+ chip->pcm->name, chip->port, irq[n], dma1[n]);
+ else
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx, irq %d, dma %d [Thinkpad]",
+ chip->pcm->name, chip->port, irq[n], dma1[n]);
error = snd_card_register(card);
if (error < 0)
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index bc9ea306ee02..f63142ec287e 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -79,7 +79,7 @@ struct snd_card_als100 {
struct snd_sb *chip;
};
-static struct pnp_card_device_id snd_als100_pnpids[] = {
+static const struct pnp_card_device_id snd_als100_pnpids[] = {
/* DT197A30 */
{ .id = "RWB1688",
.devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
@@ -222,15 +222,16 @@ static int snd_card_als100_probe(int dev,
if (pid->driver_data == SB_HW_DT019X) {
strcpy(card->driver, "DT-019X");
strcpy(card->shortname, "Diamond Tech. DT-019X");
- sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
- card->shortname, chip->name, chip->port,
- irq[dev], dma8[dev]);
+ snprintf(card->longname, sizeof(card->longname),
+ "Diamond Tech. DT-019X, %s at 0x%lx, irq %d, dma %d",
+ chip->name, chip->port, irq[dev], dma8[dev]);
} else {
strcpy(card->driver, "ALS100");
strcpy(card->shortname, "Avance Logic ALS100");
- sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
- card->shortname, chip->name, chip->port,
- irq[dev], dma8[dev], dma16[dev]);
+ snprintf(card->longname, sizeof(card->longname),
+ "Avance Logic ALS100, %s at 0x%lx, irq %d, dma %d&%d",
+ chip->name, chip->port, irq[dev], dma8[dev],
+ dma16[dev]);
}
if ((error = snd_sb16dsp_pcm(chip, 0)) < 0) {
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index fff186fa621e..4e6fad4f94d9 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -79,7 +79,7 @@ struct snd_card_azt2320 {
struct snd_wss *chip;
};
-static struct pnp_card_device_id snd_azt2320_pnpids[] = {
+static const struct pnp_card_device_id snd_azt2320_pnpids[] = {
/* PRO16V */
{ .id = "AZT1008", .devs = { { "AZT1008" }, { "AZT2001" }, } },
/* Aztech Sound Galaxy 16 */
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index f64b29ab5cc7..6b8c46942efb 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -182,7 +182,7 @@ struct snd_cmi8330 {
#ifdef CONFIG_PNP
-static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
+static const struct pnp_card_device_id snd_cmi8330_pnpids[] = {
{ .id = "CMI0001", .devs = { { "@X@0001" }, { "@@@0001" }, { "@H@0001" }, { "A@@0001" } } },
{ .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
{ .id = "" }
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index e8edd9017a2f..d90ab9558f7f 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -109,13 +109,17 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n)
if (error < 0)
goto out;
- strcpy(card->driver, "CS4231");
- strcpy(card->shortname, chip->pcm->name);
-
- sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
- chip->pcm->name, chip->port, irq[n], dma1[n]);
- if (dma2[n] >= 0)
- sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]);
+ strlcpy(card->driver, "CS4231", sizeof(card->driver));
+ strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname));
+
+ if (dma2[n] < 0)
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx, irq %d, dma %d",
+ chip->pcm->name, chip->port, irq[n], dma1[n]);
+ else
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx, irq %d, dma %d&%d",
+ chip->pcm->name, chip->port, irq[n], dma1[n], dma2[n]);
error = snd_wss_mixer(chip);
if (error < 0)
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 1f9a3b2be7a1..70559e59d18f 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -149,7 +149,7 @@ static const struct pnp_device_id snd_cs423x_pnpbiosids[] = {
MODULE_DEVICE_TABLE(pnp, snd_cs423x_pnpbiosids);
#define CS423X_ISAPNP_DRIVER "cs4232_isapnp"
-static struct pnp_card_device_id snd_cs423x_pnpids[] = {
+static const struct pnp_card_device_id snd_cs423x_pnpids[] = {
/* Philips PCA70PS */
{ .id = "CSC0d32", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } },
/* TerraTec Maestro 32/96 (CS4232) */
@@ -419,15 +419,17 @@ static int snd_cs423x_probe(struct snd_card *card, int dev)
if (err < 0)
return err;
}
- strcpy(card->driver, chip->pcm->name);
- strcpy(card->shortname, chip->pcm->name);
- sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i",
- chip->pcm->name,
- chip->port,
- irq[dev],
- dma1[dev]);
- if (dma2[dev] >= 0)
- sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
+ strlcpy(card->driver, chip->pcm->name, sizeof(card->driver));
+ strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname));
+ if (dma2[dev] < 0)
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx, irq %i, dma %i",
+ chip->pcm->name, chip->port, irq[dev], dma1[dev]);
+ else
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx, irq %i, dma %i&%d",
+ chip->pcm->name, chip->port, irq[dev], dma1[dev],
+ dma2[dev]);
err = snd_wss_timer(chip, 0);
if (err < 0)
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 36320e7f2789..a826c138e7f5 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -321,7 +321,7 @@ static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
}
#endif
-static struct pnp_card_device_id snd_es968_pnpids[] = {
+static const struct pnp_card_device_id snd_es968_pnpids[] = {
{ .id = "ESS0968", .devs = { { "@@@0968" }, } },
{ .id = "ESS0968", .devs = { { "ESS0968" }, } },
{ .id = "", } /* end */
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 5d3df96c5e5b..f9c0662e9a22 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -526,7 +526,7 @@ static snd_pcm_uframes_t snd_es1688_capture_pointer(struct snd_pcm_substream *su
*/
-static struct snd_pcm_hardware snd_es1688_playback =
+static const struct snd_pcm_hardware snd_es1688_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -544,7 +544,7 @@ static struct snd_pcm_hardware snd_es1688_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_es1688_capture =
+static const struct snd_pcm_hardware snd_es1688_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -706,7 +706,7 @@ exit:
return err;
}
-static struct snd_pcm_ops snd_es1688_playback_ops = {
+static const struct snd_pcm_ops snd_es1688_playback_ops = {
.open = snd_es1688_playback_open,
.close = snd_es1688_playback_close,
.ioctl = snd_es1688_ioctl,
@@ -717,7 +717,7 @@ static struct snd_pcm_ops snd_es1688_playback_ops = {
.pointer = snd_es1688_playback_pointer,
};
-static struct snd_pcm_ops snd_es1688_capture_ops = {
+static const struct snd_pcm_ops snd_es1688_capture_ops = {
.open = snd_es1688_capture_open,
.close = snd_es1688_capture_close,
.ioctl = snd_es1688_ioctl,
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index ae17a6584061..2a6960c3e2a4 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -838,7 +838,7 @@ static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *su
return pos >> chip->dma1_shift;
}
-static struct snd_pcm_hardware snd_es18xx_playback =
+static const struct snd_pcm_hardware snd_es18xx_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME |
@@ -858,7 +858,7 @@ static struct snd_pcm_hardware snd_es18xx_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_es18xx_capture =
+static const struct snd_pcm_hardware snd_es18xx_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME |
@@ -1665,7 +1665,7 @@ static int snd_es18xx_probe(struct snd_es18xx *chip,
return snd_es18xx_initialize(chip, mpu_port, fm_port);
}
-static struct snd_pcm_ops snd_es18xx_playback_ops = {
+static const struct snd_pcm_ops snd_es18xx_playback_ops = {
.open = snd_es18xx_playback_open,
.close = snd_es18xx_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1676,7 +1676,7 @@ static struct snd_pcm_ops snd_es18xx_playback_ops = {
.pointer = snd_es18xx_playback_pointer,
};
-static struct snd_pcm_ops snd_es18xx_capture_ops = {
+static const struct snd_pcm_ops snd_es18xx_capture_ops = {
.open = snd_es18xx_capture_open,
.close = snd_es18xx_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -2017,7 +2017,7 @@ static int isa_registered;
static int pnp_registered;
static int pnpc_registered;
-static struct pnp_device_id snd_audiodrive_pnpbiosids[] = {
+static const struct pnp_device_id snd_audiodrive_pnpbiosids[] = {
{ .id = "ESS1869" },
{ .id = "ESS1879" },
{ .id = "" } /* end */
@@ -2062,7 +2062,7 @@ static int snd_audiodrive_pnp(int dev, struct snd_es18xx *chip,
return 0;
}
-static struct pnp_card_device_id snd_audiodrive_pnpids[] = {
+static const struct pnp_card_device_id snd_audiodrive_pnpids[] = {
/* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */
{ .id = "ESS1868", .devs = { { "ESS1868" }, { "ESS0000" } } },
/* ESS 1868 (integrated on Maxisound Cards) */
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index 6b3da01a93b7..131b28997e1d 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -650,7 +650,7 @@ static void snd_gf1_pcm_interrupt_dma_read(struct snd_gus_card * gus)
}
}
-static struct snd_pcm_hardware snd_gf1_pcm_playback =
+static const struct snd_pcm_hardware snd_gf1_pcm_playback =
{
.info = SNDRV_PCM_INFO_NONINTERLEAVED,
.formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
@@ -668,7 +668,7 @@ static struct snd_pcm_hardware snd_gf1_pcm_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_gf1_pcm_capture =
+static const struct snd_pcm_hardware snd_gf1_pcm_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -842,7 +842,7 @@ static const struct snd_kcontrol_new snd_gf1_pcm_volume_control1 =
.put = snd_gf1_pcm_volume_put
};
-static struct snd_pcm_ops snd_gf1_pcm_playback_ops = {
+static const struct snd_pcm_ops snd_gf1_pcm_playback_ops = {
.open = snd_gf1_pcm_playback_open,
.close = snd_gf1_pcm_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -856,7 +856,7 @@ static struct snd_pcm_ops snd_gf1_pcm_playback_ops = {
.fill_silence = snd_gf1_pcm_playback_silence,
};
-static struct snd_pcm_ops snd_gf1_pcm_capture_ops = {
+static const struct snd_pcm_ops snd_gf1_pcm_capture_ops = {
.open = snd_gf1_pcm_capture_open,
.close = snd_gf1_pcm_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 0687b7ef3e53..a6fc26bf0af2 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -136,7 +136,7 @@ struct snd_interwave {
static int isa_registered;
static int pnp_registered;
-static struct pnp_card_device_id snd_interwave_pnpids[] = {
+static const struct pnp_card_device_id snd_interwave_pnpids[] = {
#ifndef SNDRV_STB
/* Gravis UltraSound Plug & Play */
{ .id = "GRV0001", .devs = { { .id = "GRV0000" } } },
diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c
index 8109ab3d29d1..569897f64fda 100644
--- a/sound/isa/msnd/msnd.c
+++ b/sound/isa/msnd/msnd.c
@@ -437,7 +437,7 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip,
}
}
-static struct snd_pcm_hardware snd_msnd_playback = {
+static const struct snd_pcm_hardware snd_msnd_playback = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -456,7 +456,7 @@ static struct snd_pcm_hardware snd_msnd_playback = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_msnd_capture = {
+static const struct snd_pcm_hardware snd_msnd_capture = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -572,7 +572,7 @@ snd_msnd_playback_pointer(struct snd_pcm_substream *substream)
}
-static struct snd_pcm_ops snd_msnd_playback_ops = {
+static const struct snd_pcm_ops snd_msnd_playback_ops = {
.open = snd_msnd_playback_open,
.close = snd_msnd_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -669,7 +669,7 @@ static int snd_msnd_capture_hw_params(struct snd_pcm_substream *substream,
}
-static struct snd_pcm_ops snd_msnd_capture_ops = {
+static const struct snd_pcm_ops snd_msnd_capture_ops = {
.open = snd_msnd_capture_open,
.close = snd_msnd_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index fc4fb1904aef..45e561c425bf 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -1192,7 +1192,7 @@ static void snd_msnd_pnp_remove(struct pnp_card_link *pcard)
static int isa_registered;
static int pnp_registered;
-static struct pnp_card_device_id msnd_pnpids[] = {
+static const struct pnp_card_device_id msnd_pnpids[] = {
/* Pinnacle PnP */
{ .id = "BVJ0440", .devs = { { "TBS0000" }, { "TBS0001" } } },
{ .id = "" } /* end */
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 4098e3e0353d..7cce4cd4a23b 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -141,7 +141,7 @@ struct snd_opl3sa2 {
#ifdef CONFIG_PNP
-static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = {
+static const struct pnp_device_id snd_opl3sa2_pnpbiosids[] = {
{ .id = "YMH0021" },
{ .id = "NMX2210" }, /* Gateway Solo 2500 */
{ .id = "" } /* end */
@@ -149,7 +149,7 @@ static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = {
MODULE_DEVICE_TABLE(pnp, snd_opl3sa2_pnpbiosids);
-static struct pnp_card_device_id snd_opl3sa2_pnpids[] = {
+static const struct pnp_card_device_id snd_opl3sa2_pnpids[] = {
/* Yamaha YMF719E-S (Genius Sound Maker 3DX) */
{ .id = "YMH0020", .devs = { { "YMH0021" } } },
/* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index bcbff56f060d..8894c7c18ad6 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -143,7 +143,7 @@ static int snd_miro_pnp_is_probed;
#ifdef CONFIG_PNP
-static struct pnp_card_device_id snd_miro_pnpids[] = {
+static const struct pnp_card_device_id snd_miro_pnpids[] = {
/* PCM20 and PCM12 in PnP mode */
{ .id = "MIR0924",
.devs = { { "MIR0000" }, { "MIR0002" }, { "MIR0005" } }, },
@@ -1353,9 +1353,10 @@ static int snd_miro_probe(struct snd_card *card)
}
strcpy(card->driver, "miro");
- sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d",
- card->shortname, miro->name, codec->pcm->name,
- miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2);
+ snprintf(card->longname, sizeof(card->longname),
+ "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d",
+ card->shortname, miro->name, codec->pcm->name,
+ miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2);
if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
rmidi = NULL;
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index ceddb392b1e3..505cd81e19fa 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -151,7 +151,7 @@ static int snd_opti9xx_pnp_is_probed;
#ifdef CONFIG_PNP
-static struct pnp_card_device_id snd_opti9xx_pnpids[] = {
+static const struct pnp_card_device_id snd_opti9xx_pnpids[] = {
#ifndef OPTi93X
/* OPTi 82C924 */
{ .id = "OPT0924",
@@ -879,13 +879,15 @@ static int snd_opti9xx_probe(struct snd_card *card)
strcpy(card->driver, chip->name);
sprintf(card->shortname, "OPTi %s", card->driver);
#if defined(CS4231) || defined(OPTi93X)
- sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
- card->shortname, codec->pcm->name,
- chip->wss_base + 4, irq, dma1, xdma2);
+ snprintf(card->longname, sizeof(card->longname),
+ "%s, %s at 0x%lx, irq %d, dma %d&%d",
+ card->shortname, codec->pcm->name,
+ chip->wss_base + 4, irq, dma1, xdma2);
#else
- sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
- card->shortname, codec->pcm->name, chip->wss_base + 4, irq,
- dma1);
+ snprintf(card->longname, sizeof(card->longname),
+ "%s, %s at 0x%lx, irq %d, dma %d",
+ card->shortname, codec->pcm->name, chip->wss_base + 4, irq,
+ dma1);
#endif /* CS4231 || OPTi93X */
if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c
index d28d712f99f4..5a485504f607 100644
--- a/sound/isa/sb/emu8000_callback.c
+++ b/sound/isa/sb/emu8000_callback.c
@@ -62,7 +62,7 @@ static void snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int ch);
/*
* set up operators
*/
-static struct snd_emux_operators emu8000_ops = {
+static const struct snd_emux_operators emu8000_ops = {
.owner = THIS_MODULE,
.get_voice = get_voice,
.prepare = start_voice,
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 2ee8d67871ec..8f34551abd8d 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -157,7 +157,7 @@ static int calc_rate_offset(int hz)
/*
*/
-static struct snd_pcm_hardware emu8k_pcm_hw = {
+static const struct snd_pcm_hardware emu8k_pcm_hw = {
#ifdef USE_NONINTERLEAVE
.info = SNDRV_PCM_INFO_NONINTERLEAVED,
#else
@@ -670,7 +670,7 @@ static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs)
}
-static struct snd_pcm_ops emu8k_pcm_ops = {
+static const struct snd_pcm_ops emu8k_pcm_ops = {
.open = emu8k_pcm_open,
.close = emu8k_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 917a93d696c3..8f9ebeb998f6 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -145,7 +145,7 @@ struct snd_card_sb16 {
#ifdef CONFIG_PNP
-static struct pnp_card_device_id snd_sb16_pnpids[] = {
+static const struct pnp_card_device_id snd_sb16_pnpids[] = {
#ifndef SNDRV_SBAWE
/* Sound Blaster 16 PnP */
{ .id = "CTL0024", .devs = { { "CTL0031" } } },
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index 4be1350f6649..3e39ba220c39 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -473,7 +473,7 @@ static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *subs
*/
-static struct snd_pcm_hardware snd_sb16_playback =
+static const struct snd_pcm_hardware snd_sb16_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -491,7 +491,7 @@ static struct snd_pcm_hardware snd_sb16_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_sb16_capture =
+static const struct snd_pcm_hardware snd_sb16_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -838,7 +838,7 @@ int snd_sb16dsp_configure(struct snd_sb * chip)
return 0;
}
-static struct snd_pcm_ops snd_sb16_playback_ops = {
+static const struct snd_pcm_ops snd_sb16_playback_ops = {
.open = snd_sb16_playback_open,
.close = snd_sb16_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -849,7 +849,7 @@ static struct snd_pcm_ops snd_sb16_playback_ops = {
.pointer = snd_sb16_playback_pointer,
};
-static struct snd_pcm_ops snd_sb16_capture_ops = {
+static const struct snd_pcm_ops snd_sb16_capture_ops = {
.open = snd_sb16_capture_open,
.close = snd_sb16_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 0f302be4fb6d..d45df5c54423 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -447,7 +447,7 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst
*/
-static struct snd_pcm_hardware snd_sb8_playback =
+static const struct snd_pcm_hardware snd_sb8_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -466,7 +466,7 @@ static struct snd_pcm_hardware snd_sb8_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_sb8_capture =
+static const struct snd_pcm_hardware snd_sb8_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -572,7 +572,7 @@ static int snd_sb8_close(struct snd_pcm_substream *substream)
* Initialization part
*/
-static struct snd_pcm_ops snd_sb8_playback_ops = {
+static const struct snd_pcm_ops snd_sb8_playback_ops = {
.open = snd_sb8_open,
.close = snd_sb8_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -583,7 +583,7 @@ static struct snd_pcm_ops snd_sb8_playback_ops = {
.pointer = snd_sb8_playback_pointer,
};
-static struct snd_pcm_ops snd_sb8_capture_ops = {
+static const struct snd_pcm_ops snd_sb8_capture_ops = {
.open = snd_sb8_open,
.close = snd_sb8_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 1cd2908e4f12..733adee5afbf 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -88,7 +88,7 @@ MODULE_PARM_DESC(joystick, "Enable gameport.");
static int isa_registered;
static int pnp_registered;
-static struct pnp_card_device_id sscape_pnpids[] = {
+static const struct pnp_card_device_id sscape_pnpids[] = {
{ .id = "ENS3081", .devs = { { "ENS0000" } } }, /* Soundscape PnP */
{ .id = "ENS4081", .devs = { { "ENS1011" } } }, /* VIVO90 */
{ .id = "" } /* end */
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index da4e9a85f0af..b1989facd732 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -88,7 +88,7 @@ MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly lo
static int isa_registered;
static int pnp_registered;
-static struct pnp_card_device_id snd_wavefront_pnpids[] = {
+static const struct pnp_card_device_id snd_wavefront_pnpids[] = {
/* Tropez */
{ .id = "CSC7532", .devs = { { "CSC0000" }, { "CSC0010" }, { "PnPb006" }, { "CSC0004" } } },
/* Tropez+ */
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 9f4e2e34cbe1..8a852042a066 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -1452,7 +1452,7 @@ static int snd_wss_probe(struct snd_wss *chip)
*/
-static struct snd_pcm_hardware snd_wss_playback =
+static const struct snd_pcm_hardware snd_wss_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -1472,7 +1472,7 @@ static struct snd_pcm_hardware snd_wss_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_wss_capture =
+static const struct snd_pcm_hardware snd_wss_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -1901,7 +1901,7 @@ int snd_wss_create(struct snd_card *card,
}
EXPORT_SYMBOL(snd_wss_create);
-static struct snd_pcm_ops snd_wss_playback_ops = {
+static const struct snd_pcm_ops snd_wss_playback_ops = {
.open = snd_wss_playback_open,
.close = snd_wss_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1912,7 +1912,7 @@ static struct snd_pcm_ops snd_wss_playback_ops = {
.pointer = snd_wss_playback_pointer,
};
-static struct snd_pcm_ops snd_wss_capture_ops = {
+static const struct snd_pcm_ops snd_wss_capture_ops = {
.open = snd_wss_capture_open,
.close = snd_wss_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index 3318c15e324a..37d378a26a50 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -496,7 +496,7 @@ static void hal2_free_dmabuf(struct hal2_codec *codec)
DMA_ATTR_NON_CONSISTENT);
}
-static struct snd_pcm_hardware hal2_pcm_hw = {
+static const struct snd_pcm_hardware hal2_pcm_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -711,7 +711,7 @@ static int hal2_capture_ack(struct snd_pcm_substream *substream)
hal2_capture_transfer);
}
-static struct snd_pcm_ops hal2_playback_ops = {
+static const struct snd_pcm_ops hal2_playback_ops = {
.open = hal2_playback_open,
.close = hal2_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -723,7 +723,7 @@ static struct snd_pcm_ops hal2_playback_ops = {
.ack = hal2_playback_ack,
};
-static struct snd_pcm_ops hal2_capture_ops = {
+static const struct snd_pcm_ops hal2_capture_ops = {
.open = hal2_capture_open,
.close = hal2_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index 0ebc1c3727df..71c942162c25 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -532,7 +532,7 @@ static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id)
/* PCM part */
/* PCM hardware definition */
-static struct snd_pcm_hardware snd_sgio2audio_pcm_hw = {
+static const struct snd_pcm_hardware snd_sgio2audio_pcm_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -675,7 +675,7 @@ snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
}
/* operators */
-static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
+static const struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
.open = snd_sgio2audio_playback1_open,
.close = snd_sgio2audio_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -688,7 +688,7 @@ static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
.mmap = snd_pcm_lib_mmap_vmalloc,
};
-static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
+static const struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
.open = snd_sgio2audio_playback2_open,
.close = snd_sgio2audio_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -701,7 +701,7 @@ static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
.mmap = snd_pcm_lib_mmap_vmalloc,
};
-static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
+static const struct snd_pcm_ops snd_sgio2audio_capture_ops = {
.open = snd_sgio2audio_capture_open,
.close = snd_sgio2audio_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index 5e04c2b4fbc1..f36e7006e00c 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -260,7 +260,7 @@ snd_harmony_rate_bits(int rate)
return HARMONY_SR_44KHZ;
}
-static struct snd_pcm_hardware snd_harmony_playback =
+static const struct snd_pcm_hardware snd_harmony_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
@@ -281,7 +281,7 @@ static struct snd_pcm_hardware snd_harmony_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_harmony_capture =
+static const struct snd_pcm_hardware snd_harmony_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
@@ -596,7 +596,7 @@ snd_harmony_hw_free(struct snd_pcm_substream *ss)
return snd_pcm_lib_free_pages(ss);
}
-static struct snd_pcm_ops snd_harmony_playback_ops = {
+static const struct snd_pcm_ops snd_harmony_playback_ops = {
.open = snd_harmony_playback_open,
.close = snd_harmony_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -607,7 +607,7 @@ static struct snd_pcm_ops snd_harmony_playback_ops = {
.pointer = snd_harmony_playback_pointer,
};
-static struct snd_pcm_ops snd_harmony_capture_ops = {
+static const struct snd_pcm_ops snd_harmony_capture_ops = {
.open = snd_harmony_capture_open,
.close = snd_harmony_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 8c36990e26f6..0bf2c04eeada 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -283,7 +283,7 @@ snd_ad1889_hw_free(struct snd_pcm_substream *substream)
return snd_pcm_lib_free_pages(substream);
}
-static struct snd_pcm_hardware snd_ad1889_playback_hw = {
+static const struct snd_pcm_hardware snd_ad1889_playback_hw = {
.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -300,7 +300,7 @@ static struct snd_pcm_hardware snd_ad1889_playback_hw = {
/*.fifo_size = 0,*/
};
-static struct snd_pcm_hardware snd_ad1889_capture_hw = {
+static const struct snd_pcm_hardware snd_ad1889_capture_hw = {
.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 8567f1e5b9cf..39547e32e584 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1540,7 +1540,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_ops snd_ali_playback_ops = {
+static const struct snd_pcm_ops snd_ali_playback_ops = {
.open = snd_ali_playback_open,
.close = snd_ali_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1551,7 +1551,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = {
.pointer = snd_ali_playback_pointer,
};
-static struct snd_pcm_ops snd_ali_capture_ops = {
+static const struct snd_pcm_ops snd_ali_capture_ops = {
.open = snd_ali_capture_open,
.close = snd_ali_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1626,7 +1626,7 @@ static int snd_ali_modem_capture_open(struct snd_pcm_substream *substream)
return snd_ali_modem_open(substream, 1, ALI_MODEM_IN_CHANNEL);
}
-static struct snd_pcm_ops snd_ali_modem_playback_ops = {
+static const struct snd_pcm_ops snd_ali_modem_playback_ops = {
.open = snd_ali_modem_playback_open,
.close = snd_ali_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1637,7 +1637,7 @@ static struct snd_pcm_ops snd_ali_modem_playback_ops = {
.pointer = snd_ali_pointer,
};
-static struct snd_pcm_ops snd_ali_modem_capture_ops = {
+static const struct snd_pcm_ops snd_ali_modem_capture_ops = {
.open = snd_ali_modem_capture_open,
.close = snd_ali_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1653,8 +1653,8 @@ struct ali_pcm_description {
char *name;
unsigned int playback_num;
unsigned int capture_num;
- struct snd_pcm_ops *playback_ops;
- struct snd_pcm_ops *capture_ops;
+ const struct snd_pcm_ops *playback_ops;
+ const struct snd_pcm_ops *capture_ops;
unsigned short class;
};
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index ab75601d7c2c..eaa2d853d922 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -328,7 +328,7 @@ static int snd_als300_ac97(struct snd_als300 *chip)
* the card when it is running outside of legacy
* mode.
*/
-static struct snd_pcm_hardware snd_als300_playback_hw =
+static const struct snd_pcm_hardware snd_als300_playback_hw =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -347,7 +347,7 @@ static struct snd_pcm_hardware snd_als300_playback_hw =
.periods_max = 2,
};
-static struct snd_pcm_hardware snd_als300_capture_hw =
+static const struct snd_pcm_hardware snd_als300_capture_hw =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 7844a75d8ed9..26b097edec8c 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -592,7 +592,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id)
/*****************************************************************/
-static struct snd_pcm_hardware snd_als4000_playback =
+static const struct snd_pcm_hardware snd_als4000_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
@@ -611,7 +611,7 @@ static struct snd_pcm_hardware snd_als4000_playback =
.fifo_size = 0
};
-static struct snd_pcm_hardware snd_als4000_capture =
+static const struct snd_pcm_hardware snd_als4000_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID),
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
index ac86a1f1d3bf..9e122327dc05 100644
--- a/sound/pci/asihpi/hpidebug.c
+++ b/sound/pci/asihpi/hpidebug.c
@@ -71,8 +71,8 @@ void hpi_debug_data(u16 *pdata, u32 len)
printk(KERN_DEBUG "%p:", (pdata + i));
for (k = 0; k < cols && i < len; i++, k++)
- printk("%s%04x", k == 0 ? "" : " ", pdata[i]);
+ printk(KERN_CONT "%s%04x", k == 0 ? "" : " ", pdata[i]);
- printk("\n");
+ printk(KERN_CONT "\n");
}
}
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index a40c918c8dff..7ae63d452bba 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1009,7 +1009,7 @@ static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream)
/*
* pcm hardware definition, identical for all DMA types
*/
-static struct snd_pcm_hardware snd_atiixp_pcm_hw =
+static const struct snd_pcm_hardware snd_atiixp_pcm_hw =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1183,7 +1183,7 @@ static const struct snd_pcm_ops snd_atiixp_spdif_ops = {
.pointer = snd_atiixp_pcm_pointer,
};
-static struct ac97_pcm atiixp_pcm_defs[] = {
+static const struct ac97_pcm atiixp_pcm_defs[] = {
/* front PCM */
{
.exclusive = 1,
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 52e0ea7b9b80..a586635664e0 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -834,7 +834,7 @@ static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream)
/*
* pcm hardware definition, identical for all DMA types
*/
-static struct snd_pcm_hardware snd_atiixp_pcm_hw =
+static const struct snd_pcm_hardware snd_atiixp_pcm_hw =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 1aa97012451d..53714e0bf598 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -30,7 +30,7 @@
#define VORTEX_PCM_TYPE(x) (x->name[40])
/* hardware definition */
-static struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
+static const struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
.info =
(SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
@@ -51,7 +51,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
};
#ifndef CHIP_AU8820
-static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
+static const struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
.info =
(SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
@@ -71,7 +71,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
.periods_max = 64,
};
#endif
-static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
+static const struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
.info =
(SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
@@ -94,7 +94,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
};
#ifndef CHIP_AU8810
-static struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
+static const struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
@@ -439,7 +439,7 @@ static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substr
}
/* operators */
-static struct snd_pcm_ops snd_vortex_playback_ops = {
+static const struct snd_pcm_ops snd_vortex_playback_ops = {
.open = snd_vortex_pcm_open,
.close = snd_vortex_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 8356180bfe0e..9a49e4243a9c 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -52,7 +52,7 @@ MODULE_LICENSE("GPL");
* TYPEDEFS
********************************/
/* hardware definition */
-static struct snd_pcm_hardware snd_aw2_playback_hw = {
+static const struct snd_pcm_hardware snd_aw2_playback_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
@@ -69,7 +69,7 @@ static struct snd_pcm_hardware snd_aw2_playback_hw = {
.periods_max = 1024,
};
-static struct snd_pcm_hardware snd_aw2_capture_hw = {
+static const struct snd_pcm_hardware snd_aw2_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index de0234294c25..d8ade8771a32 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -353,7 +353,7 @@ static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct snd_pcm_hardware snd_bt87x_digital_hw = {
+static const struct snd_pcm_hardware snd_bt87x_digital_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -370,7 +370,7 @@ static struct snd_pcm_hardware snd_bt87x_digital_hw = {
.periods_max = 255,
};
-static struct snd_pcm_hardware snd_bt87x_analog_hw = {
+static const struct snd_pcm_hardware snd_bt87x_analog_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 6165a57a94ae..cd27b5536654 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -296,7 +296,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
};
/* hardware definition */
-static struct snd_pcm_hardware snd_ca0106_playback_hw = {
+static const struct snd_pcm_hardware snd_ca0106_playback_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -317,7 +317,7 @@ static struct snd_pcm_hardware snd_ca0106_playback_hw = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_ca0106_capture_hw = {
+static const struct snd_pcm_hardware snd_ca0106_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -660,11 +660,9 @@ static int snd_ca0106_pcm_open_capture_channel(struct snd_pcm_substream *substre
int err;
epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
- if (epcm == NULL) {
- dev_err(chip->card->dev,
- "open_capture_channel: failed epcm alloc\n");
+ if (!epcm)
return -ENOMEM;
- }
+
epcm->emu = chip;
epcm->substream = substream;
epcm->channel_id=channel_id;
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index a460cb63e971..26a657870664 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -1477,7 +1477,7 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id)
*/
/* playback on channel A */
-static struct snd_pcm_hardware snd_cmipci_playback =
+static const struct snd_pcm_hardware snd_cmipci_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1497,7 +1497,7 @@ static struct snd_pcm_hardware snd_cmipci_playback =
};
/* capture on channel B */
-static struct snd_pcm_hardware snd_cmipci_capture =
+static const struct snd_pcm_hardware snd_cmipci_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1517,7 +1517,7 @@ static struct snd_pcm_hardware snd_cmipci_capture =
};
/* playback on channel B - stereo 16bit only? */
-static struct snd_pcm_hardware snd_cmipci_playback2 =
+static const struct snd_pcm_hardware snd_cmipci_playback2 =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1537,7 +1537,7 @@ static struct snd_pcm_hardware snd_cmipci_playback2 =
};
/* spdif playback on channel A */
-static struct snd_pcm_hardware snd_cmipci_playback_spdif =
+static const struct snd_pcm_hardware snd_cmipci_playback_spdif =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1557,7 +1557,7 @@ static struct snd_pcm_hardware snd_cmipci_playback_spdif =
};
/* spdif playback on channel A (32bit, IEC958 subframes) */
-static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe =
+static const struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1577,7 +1577,7 @@ static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe =
};
/* spdif capture on channel B */
-static struct snd_pcm_hardware snd_cmipci_capture_spdif =
+static const struct snd_pcm_hardware snd_cmipci_capture_spdif =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -3295,20 +3295,23 @@ static int snd_cmipci_probe(struct pci_dev *pci,
break;
}
- if ((err = snd_cmipci_create(card, pci, dev, &cm)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_cmipci_create(card, pci, dev, &cm);
+ if (err < 0)
+ goto free_card;
+
card->private_data = cm;
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_card_register(card);
+ if (err < 0)
+ goto free_card;
+
pci_set_drvdata(pci, card);
dev++;
return 0;
+free_card:
+ snd_card_free(card);
+ return err;
}
static void snd_cmipci_remove(struct pci_dev *pci)
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index ee7ba4b0b47b..ec4247638fa1 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -847,7 +847,7 @@ static snd_pcm_uframes_t snd_cs4281_pointer(struct snd_pcm_substream *substream)
snd_cs4281_peekBA0(chip, dma->regDCC) - 1;
}
-static struct snd_pcm_hardware snd_cs4281_playback =
+static const struct snd_pcm_hardware snd_cs4281_playback =
{
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -872,7 +872,7 @@ static struct snd_pcm_hardware snd_cs4281_playback =
.fifo_size = CS4281_FIFO_SIZE,
};
-static struct snd_pcm_hardware snd_cs4281_capture =
+static const struct snd_pcm_hardware snd_cs4281_capture =
{
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 709fb1a503b7..0020fd0efc46 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1438,7 +1438,7 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct snd_pcm_hardware snd_cs46xx_playback =
+static const struct snd_pcm_hardware snd_cs46xx_playback =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -1460,7 +1460,7 @@ static struct snd_pcm_hardware snd_cs46xx_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_cs46xx_capture =
+static const struct snd_pcm_hardware snd_cs46xx_capture =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index c208c1d8dbb2..ee7065f6e162 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -33,7 +33,7 @@
#include <sound/ac97_codec.h>
#include "cs5535audio.h"
-static struct snd_pcm_hardware snd_cs5535audio_playback =
+static const struct snd_pcm_hardware snd_cs5535audio_playback =
{
.info = (
SNDRV_PCM_INFO_MMAP |
@@ -62,7 +62,7 @@ static struct snd_pcm_hardware snd_cs5535audio_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_cs5535audio_capture =
+static const struct snd_pcm_hardware snd_cs5535audio_capture =
{
.info = (
SNDRV_PCM_INFO_MMAP |
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index 79edd88d5cd0..8e6eb9d7984b 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -2154,7 +2154,7 @@ static void hw_write_pci(struct hw *hw, u32 reg, u32 data)
&container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags);
}
-static struct hw ct20k1_preset = {
+static const struct hw ct20k1_preset = {
.irq = -1,
.card_init = hw_card_init,
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index 18ee7768b7c4..b866d6b2c923 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -2220,7 +2220,7 @@ static void hw_write_20kx(struct hw *hw, u32 reg, u32 data)
writel(data, hw->mem_base + reg);
}
-static struct hw ct20k2_preset = {
+static const struct hw ct20k2_preset = {
.irq = -1,
.card_init = hw_card_init,
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index 974978041558..b36e37ae2b51 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -21,7 +21,7 @@
#include <sound/pcm.h>
/* Hardware descriptions for playback */
-static struct snd_pcm_hardware ct_pcm_playback_hw = {
+static const struct snd_pcm_hardware ct_pcm_playback_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -46,7 +46,7 @@ static struct snd_pcm_hardware ct_pcm_playback_hw = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
+static const struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -69,7 +69,7 @@ static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
};
/* Hardware descriptions for capture */
-static struct snd_pcm_hardware ct_pcm_capture_hw = {
+static const struct snd_pcm_hardware ct_pcm_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -140,27 +140,28 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
err = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- kfree(apcm);
- return err;
- }
+ if (err < 0)
+ goto free_pcm;
+
err = snd_pcm_hw_constraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1024, UINT_MAX);
- if (err < 0) {
- kfree(apcm);
- return err;
- }
+ if (err < 0)
+ goto free_pcm;
apcm->timer = ct_timer_instance_new(atc->timer, apcm);
if (!apcm->timer) {
- kfree(apcm);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto free_pcm;
}
runtime->private_data = apcm;
runtime->private_free = ct_atc_pcm_free_substream;
return 0;
+
+free_pcm:
+ kfree(apcm);
+ return err;
}
static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
@@ -286,27 +287,28 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
err = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
- if (err < 0) {
- kfree(apcm);
- return err;
- }
+ if (err < 0)
+ goto free_pcm;
+
err = snd_pcm_hw_constraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1024, UINT_MAX);
- if (err < 0) {
- kfree(apcm);
- return err;
- }
+ if (err < 0)
+ goto free_pcm;
apcm->timer = ct_timer_instance_new(atc->timer, apcm);
if (!apcm->timer) {
- kfree(apcm);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto free_pcm;
}
runtime->private_data = apcm;
runtime->private_free = ct_atc_pcm_free_substream;
return 0;
+
+free_pcm:
+ kfree(apcm);
+ return err;
}
static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
diff --git a/sound/pci/ctxfi/ctresource.c b/sound/pci/ctxfi/ctresource.c
index c5124c3c0fd1..80c4d84f9667 100644
--- a/sound/pci/ctxfi/ctresource.c
+++ b/sound/pci/ctxfi/ctresource.c
@@ -258,10 +258,8 @@ error:
int rsc_mgr_uninit(struct rsc_mgr *mgr)
{
- if (NULL != mgr->rscs) {
- kfree(mgr->rscs);
- mgr->rscs = NULL;
- }
+ kfree(mgr->rscs);
+ mgr->rscs = NULL;
if ((NULL != mgr->hw) && (NULL != mgr->ctrl_blk)) {
switch (mgr->type) {
diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c
index a5a72df29801..bb4c9c3c89ae 100644
--- a/sound/pci/ctxfi/ctsrc.c
+++ b/sound/pci/ctxfi/ctsrc.c
@@ -702,10 +702,8 @@ error1:
static int srcimp_rsc_uninit(struct srcimp *srcimp)
{
- if (NULL != srcimp->imappers) {
- kfree(srcimp->imappers);
- srcimp->imappers = NULL;
- }
+ kfree(srcimp->imappers);
+ srcimp->imappers = NULL;
srcimp->ops = NULL;
srcimp->mgr = NULL;
rsc_uninit(&srcimp->rsc);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index d15ecf9febbf..7326695bca33 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -826,7 +826,7 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream)
/* pcm *_ops structures */
-static struct snd_pcm_ops analog_playback_ops = {
+static const struct snd_pcm_ops analog_playback_ops = {
.open = pcm_analog_out_open,
.close = pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -837,7 +837,7 @@ static struct snd_pcm_ops analog_playback_ops = {
.pointer = pcm_pointer,
.page = snd_pcm_sgbuf_ops_page,
};
-static struct snd_pcm_ops analog_capture_ops = {
+static const struct snd_pcm_ops analog_capture_ops = {
.open = pcm_analog_in_open,
.close = pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -850,7 +850,7 @@ static struct snd_pcm_ops analog_capture_ops = {
};
#ifdef ECHOCARD_HAS_DIGITAL_IO
#ifndef ECHOCARD_HAS_VMIXER
-static struct snd_pcm_ops digital_playback_ops = {
+static const struct snd_pcm_ops digital_playback_ops = {
.open = pcm_digital_out_open,
.close = pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -862,7 +862,7 @@ static struct snd_pcm_ops digital_playback_ops = {
.page = snd_pcm_sgbuf_ops_page,
};
#endif /* !ECHOCARD_HAS_VMIXER */
-static struct snd_pcm_ops digital_capture_ops = {
+static const struct snd_pcm_ops digital_capture_ops = {
.open = pcm_digital_in_open,
.close = pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 77a4413f4564..2c2b12a06177 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -254,7 +254,7 @@ struct emu10k1x {
};
/* hardware definition */
-static struct snd_pcm_hardware snd_emu10k1x_playback_hw = {
+static const struct snd_pcm_hardware snd_emu10k1x_playback_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -273,7 +273,7 @@ static struct snd_pcm_hardware snd_emu10k1x_playback_hw = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_emu10k1x_capture_hw = {
+static const struct snd_pcm_hardware snd_emu10k1x_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 5c9054a9f69e..2683b9717215 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -556,7 +556,7 @@ static int snd_emu10k1_efx_playback_prepare(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_hardware snd_emu10k1_efx_playback =
+static const struct snd_pcm_hardware snd_emu10k1_efx_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_NONINTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -975,7 +975,7 @@ static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *s
* Playback support device description
*/
-static struct snd_pcm_hardware snd_emu10k1_playback =
+static const struct snd_pcm_hardware snd_emu10k1_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -999,7 +999,7 @@ static struct snd_pcm_hardware snd_emu10k1_playback =
* Capture support device description
*/
-static struct snd_pcm_hardware snd_emu10k1_capture =
+static const struct snd_pcm_hardware snd_emu10k1_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1019,7 +1019,7 @@ static struct snd_pcm_hardware snd_emu10k1_capture =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_emu10k1_capture_efx =
+static const struct snd_pcm_hardware snd_emu10k1_capture_efx =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1742,7 +1742,7 @@ static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(struct snd_pcm_subs
return snd_pcm_indirect_playback_pointer(substream, &pcm->pcm_rec, ptr);
}
-static struct snd_pcm_hardware snd_emu10k1_fx8010_playback =
+static const struct snd_pcm_hardware snd_emu10k1_fx8010_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_RESUME |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index c11f1a29f35d..a30da78a95b7 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -122,7 +122,7 @@
*/
/* hardware definition */
-static struct snd_pcm_hardware snd_p16v_playback_hw = {
+static const struct snd_pcm_hardware snd_p16v_playback_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -143,7 +143,7 @@ static struct snd_pcm_hardware snd_p16v_playback_hw = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_p16v_capture_hw = {
+static const struct snd_pcm_hardware snd_p16v_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index f0d978e3b274..d4cd6451fdca 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -1059,7 +1059,7 @@ static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *s
return ptr;
}
-static struct snd_pcm_hardware snd_ensoniq_playback1 =
+static const struct snd_pcm_hardware snd_ensoniq_playback1 =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1086,7 +1086,7 @@ static struct snd_pcm_hardware snd_ensoniq_playback1 =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_ensoniq_playback2 =
+static const struct snd_pcm_hardware snd_ensoniq_playback2 =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1106,7 +1106,7 @@ static struct snd_pcm_hardware snd_ensoniq_playback2 =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_ensoniq_capture =
+static const struct snd_pcm_hardware snd_ensoniq_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 069902a06f00..9d248eb2e26c 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -900,7 +900,7 @@ static int snd_es1938_pcm_hw_free(struct snd_pcm_substream *substream)
/* ----------------------------------------------------------------------
* Audio1 Capture (ADC)
* ----------------------------------------------------------------------*/
-static struct snd_pcm_hardware snd_es1938_capture =
+static const struct snd_pcm_hardware snd_es1938_capture =
{
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER),
@@ -922,7 +922,7 @@ static struct snd_pcm_hardware snd_es1938_capture =
/* -----------------------------------------------------------------------
* Audio2 Playback (DAC)
* -----------------------------------------------------------------------*/
-static struct snd_pcm_hardware snd_es1938_playback =
+static const struct snd_pcm_hardware snd_es1938_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 2ec2b1ce0af6..0b1845ca6005 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1290,7 +1290,7 @@ static snd_pcm_uframes_t snd_es1968_pcm_pointer(struct snd_pcm_substream *substr
return bytes_to_frames(substream->runtime, ptr % es->dma_size);
}
-static struct snd_pcm_hardware snd_es1968_playback = {
+static const struct snd_pcm_hardware snd_es1968_playback = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -1311,7 +1311,7 @@ static struct snd_pcm_hardware snd_es1968_playback = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_es1968_capture = {
+static const struct snd_pcm_hardware snd_es1968_capture = {
.info = (SNDRV_PCM_INFO_NONINTERLEAVED |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 8e6b04b39dcc..73a67bc3586b 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -599,7 +599,7 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct snd_pcm_hardware snd_fm801_playback =
+static const struct snd_pcm_hardware snd_fm801_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -619,7 +619,7 @@ static struct snd_pcm_hardware snd_fm801_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_fm801_capture =
+static const struct snd_pcm_hardware snd_fm801_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c
index 7efa7bd7acb2..44b1e15682b9 100644
--- a/sound/pci/hda/dell_wmi_helper.c
+++ b/sound/pci/hda/dell_wmi_helper.c
@@ -5,12 +5,47 @@
#if IS_ENABLED(CONFIG_DELL_LAPTOP)
#include <linux/dell-led.h>
+enum {
+ MICMUTE_LED_ON,
+ MICMUTE_LED_OFF,
+ MICMUTE_LED_FOLLOW_CAPTURE,
+ MICMUTE_LED_FOLLOW_MUTE,
+};
+
+static int dell_led_mode = MICMUTE_LED_FOLLOW_MUTE;
+static int dell_capture;
static int dell_led_value;
static int (*dell_micmute_led_set_func)(int);
static void (*dell_old_cap_hook)(struct hda_codec *,
struct snd_kcontrol *,
struct snd_ctl_elem_value *);
+static void call_micmute_led_update(void)
+{
+ int val;
+
+ switch (dell_led_mode) {
+ case MICMUTE_LED_ON:
+ val = 1;
+ break;
+ case MICMUTE_LED_OFF:
+ val = 0;
+ break;
+ case MICMUTE_LED_FOLLOW_CAPTURE:
+ val = dell_capture;
+ break;
+ case MICMUTE_LED_FOLLOW_MUTE:
+ default:
+ val = !dell_capture;
+ break;
+ }
+
+ if (val == dell_led_value)
+ return;
+ dell_led_value = val;
+ dell_micmute_led_set_func(dell_led_value);
+}
+
static void update_dell_wmi_micmute_led(struct hda_codec *codec,
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -22,15 +57,54 @@ static void update_dell_wmi_micmute_led(struct hda_codec *codec,
return;
if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
/* TODO: How do I verify if it's a mono or stereo here? */
- int val = (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) ? 0 : 1;
- if (val == dell_led_value)
- return;
- dell_led_value = val;
- if (dell_micmute_led_set_func)
- dell_micmute_led_set_func(dell_led_value);
+ dell_capture = (ucontrol->value.integer.value[0] ||
+ ucontrol->value.integer.value[1]);
+ call_micmute_led_update();
}
}
+static int dell_mic_mute_led_mode_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ static const char * const texts[] = {
+ "On", "Off", "Follow Capture", "Follow Mute",
+ };
+
+ return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
+}
+
+static int dell_mic_mute_led_mode_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.enumerated.item[0] = dell_led_mode;
+ return 0;
+}
+
+static int dell_mic_mute_led_mode_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ unsigned int mode;
+
+ mode = ucontrol->value.enumerated.item[0];
+ if (mode > MICMUTE_LED_FOLLOW_MUTE)
+ mode = MICMUTE_LED_FOLLOW_MUTE;
+ if (mode == dell_led_mode)
+ return 0;
+ dell_led_mode = mode;
+ call_micmute_led_update();
+ return 1;
+}
+
+static const struct snd_kcontrol_new dell_mic_mute_mode_ctls[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Mic Mute-LED Mode",
+ .info = dell_mic_mute_led_mode_info,
+ .get = dell_mic_mute_led_mode_get,
+ .put = dell_mic_mute_led_mode_put,
+ },
+ {}
+};
static void alc_fixup_dell_wmi(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
@@ -55,6 +129,7 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec,
dell_old_cap_hook = spec->gen.cap_sync_hook;
spec->gen.cap_sync_hook = update_dell_wmi_micmute_led;
removefunc = false;
+ add_mixer(spec, dell_mic_mute_mode_ctls);
}
}
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index 6efadbfb3fe3..d361bb77ca00 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -100,7 +100,7 @@ static int hda_codec_driver_probe(struct device *dev)
if (patch) {
err = patch(codec);
if (err < 0)
- goto error_module;
+ goto error_module_put;
}
err = snd_hda_codec_build_pcms(codec);
@@ -120,6 +120,9 @@ static int hda_codec_driver_probe(struct device *dev)
return 0;
error_module:
+ if (codec->patch_ops.free)
+ codec->patch_ops.free(codec);
+ error_module_put:
module_put(owner);
error:
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 821aad374a06..3db26c451837 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -3213,8 +3213,10 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
continue; /* no substreams assigned */
dev = get_empty_pcm_device(bus, cpcm->pcm_type);
- if (dev < 0)
+ if (dev < 0) {
+ cpcm->device = SNDRV_PCM_INVALID_DEVICE;
continue; /* no fatal error */
+ }
cpcm->device = dev;
err = snd_hda_attach_pcm_stream(bus, codec, cpcm);
if (err < 0) {
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 60ce1cfc300f..681c360f29f9 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -164,6 +164,7 @@ enum {
HDA_PCM_NTYPES
};
+#define SNDRV_PCM_INVALID_DEVICE (-1)
/* for PCM creation */
struct hda_pcm {
char *name;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 5ae8ddab6412..f958d8d54d15 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2389,6 +2389,9 @@ static const struct pci_device_id azx_ids[] = {
/* Coffelake */
{ PCI_DEVICE(0x8086, 0xa348),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+ /* Cannonlake */
+ { PCI_DEVICE(0x8086, 0x9dc8),
+ .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* Broxton-P(Apollolake) */
{ PCI_DEVICE(0x8086, 0x5a98),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index e0fb8c6d1bc2..757857313426 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -505,7 +505,7 @@ static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
return 1;
}
-static struct snd_kcontrol_new ad1983_auto_smux_mixer = {
+static const struct snd_kcontrol_new ad1983_auto_smux_mixer = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC958 Playback Source",
.info = ad1983_auto_smux_enum_info,
@@ -788,7 +788,7 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
return 1;
}
-static struct snd_kcontrol_new ad1988_auto_smux_mixer = {
+static const struct snd_kcontrol_new ad1988_auto_smux_mixer = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC958 Playback Source",
.info = ad1988_auto_smux_enum_info,
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index a148176c16a9..3e73d5c6ccfc 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -4774,13 +4774,17 @@ static int patch_ca0132(struct hda_codec *codec)
err = ca0132_prepare_verbs(codec);
if (err < 0)
- return err;
+ goto error;
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
if (err < 0)
- return err;
+ goto error;
return 0;
+
+ error:
+ ca0132_free(codec);
+ return err;
}
/*
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 53f9311370de..2b64fabd5faa 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2126,7 +2126,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
static int generic_hdmi_build_controls(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
- int err;
+ int dev, err;
int pin_idx, pcm_idx;
@@ -2154,11 +2154,13 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
return err;
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
- /* add control for ELD Bytes */
- err = hdmi_create_eld_ctl(codec, pcm_idx,
- get_pcm_rec(spec, pcm_idx)->device);
- if (err < 0)
- return err;
+ dev = get_pcm_rec(spec, pcm_idx)->device;
+ if (dev != SNDRV_PCM_INVALID_DEVICE) {
+ /* add control for ELD Bytes */
+ err = hdmi_create_eld_ctl(codec, pcm_idx, dev);
+ if (err < 0)
+ return err;
+ }
}
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 217bb582aff1..0ce71111b4e3 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5263,6 +5263,7 @@ enum {
ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE,
ALC233_FIXUP_LENOVO_MULTI_CODECS,
ALC294_FIXUP_LENOVO_MIC_LOCATION,
+ ALC700_FIXUP_INTEL_REFERENCE,
};
static const struct hda_fixup alc269_fixups[] = {
@@ -6058,6 +6059,21 @@ static const struct hda_fixup alc269_fixups[] = {
{ }
},
},
+ [ALC700_FIXUP_INTEL_REFERENCE] = {
+ .type = HDA_FIXUP_VERBS,
+ .v.verbs = (const struct hda_verb[]) {
+ /* Enables internal speaker */
+ {0x20, AC_VERB_SET_COEF_INDEX, 0x45},
+ {0x20, AC_VERB_SET_PROC_COEF, 0x5289},
+ {0x20, AC_VERB_SET_COEF_INDEX, 0x4A},
+ {0x20, AC_VERB_SET_PROC_COEF, 0x001b},
+ {0x58, AC_VERB_SET_COEF_INDEX, 0x00},
+ {0x58, AC_VERB_SET_PROC_COEF, 0x3888},
+ {0x20, AC_VERB_SET_COEF_INDEX, 0x6f},
+ {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b},
+ {}
+ }
+ },
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -6209,6 +6225,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
+ SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6cefdf6c0b75..63d15b545b33 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -961,7 +961,7 @@ static int stac_smux_enum_put(struct snd_kcontrol *kcontrol,
&spec->cur_smux[smux_idx]);
}
-static struct snd_kcontrol_new stac_smux_mixer = {
+static const struct snd_kcontrol_new stac_smux_mixer = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "IEC958 Playback Source",
/* count set later */
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index da5f37b7fdd0..6808bed0105e 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -445,7 +445,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status =
* initialize the chips on M-Audio cards
*/
-static struct snd_akm4xxx akm_audiophile = {
+static const struct snd_akm4xxx akm_audiophile = {
.type = SND_AK4528,
.num_adcs = 2,
.num_dacs = 2,
@@ -454,7 +454,7 @@ static struct snd_akm4xxx akm_audiophile = {
}
};
-static struct snd_ak4xxx_private akm_audiophile_priv = {
+static const struct snd_ak4xxx_private akm_audiophile_priv = {
.caddr = 2,
.cif = 0,
.data_mask = ICE1712_DELTA_AP_DOUT,
@@ -466,7 +466,7 @@ static struct snd_ak4xxx_private akm_audiophile_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_delta410 = {
+static const struct snd_akm4xxx akm_delta410 = {
.type = SND_AK4529,
.num_adcs = 2,
.num_dacs = 8,
@@ -475,7 +475,7 @@ static struct snd_akm4xxx akm_delta410 = {
}
};
-static struct snd_ak4xxx_private akm_delta410_priv = {
+static const struct snd_ak4xxx_private akm_delta410_priv = {
.caddr = 0,
.cif = 0,
.data_mask = ICE1712_DELTA_AP_DOUT,
@@ -487,7 +487,7 @@ static struct snd_ak4xxx_private akm_delta410_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_delta1010lt = {
+static const struct snd_akm4xxx akm_delta1010lt = {
.type = SND_AK4524,
.num_adcs = 8,
.num_dacs = 8,
@@ -497,7 +497,7 @@ static struct snd_akm4xxx akm_delta1010lt = {
}
};
-static struct snd_ak4xxx_private akm_delta1010lt_priv = {
+static const struct snd_ak4xxx_private akm_delta1010lt_priv = {
.caddr = 2,
.cif = 0, /* the default level of the CIF pin from AK4524 */
.data_mask = ICE1712_DELTA_1010LT_DOUT,
@@ -509,7 +509,7 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_delta66e = {
+static const struct snd_akm4xxx akm_delta66e = {
.type = SND_AK4524,
.num_adcs = 4,
.num_dacs = 4,
@@ -519,7 +519,7 @@ static struct snd_akm4xxx akm_delta66e = {
}
};
-static struct snd_ak4xxx_private akm_delta66e_priv = {
+static const struct snd_ak4xxx_private akm_delta66e_priv = {
.caddr = 2,
.cif = 0, /* the default level of the CIF pin from AK4524 */
.data_mask = ICE1712_DELTA_66E_DOUT,
@@ -532,7 +532,7 @@ static struct snd_ak4xxx_private akm_delta66e_priv = {
};
-static struct snd_akm4xxx akm_delta44 = {
+static const struct snd_akm4xxx akm_delta44 = {
.type = SND_AK4524,
.num_adcs = 4,
.num_dacs = 4,
@@ -542,7 +542,7 @@ static struct snd_akm4xxx akm_delta44 = {
}
};
-static struct snd_ak4xxx_private akm_delta44_priv = {
+static const struct snd_ak4xxx_private akm_delta44_priv = {
.caddr = 2,
.cif = 0, /* the default level of the CIF pin from AK4524 */
.data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
@@ -554,7 +554,7 @@ static struct snd_ak4xxx_private akm_delta44_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_vx442 = {
+static const struct snd_akm4xxx akm_vx442 = {
.type = SND_AK4524,
.num_adcs = 4,
.num_dacs = 4,
@@ -564,7 +564,7 @@ static struct snd_akm4xxx akm_vx442 = {
}
};
-static struct snd_ak4xxx_private akm_vx442_priv = {
+static const struct snd_ak4xxx_private akm_vx442_priv = {
.caddr = 2,
.cif = 0,
.data_mask = ICE1712_VX442_DOUT,
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index ec07136fc288..b8af747ecb43 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -344,7 +344,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
/*
*/
-static struct snd_akm4xxx akm_ews88mt = {
+static const struct snd_akm4xxx akm_ews88mt = {
.num_adcs = 8,
.num_dacs = 8,
.type = SND_AK4524,
@@ -354,7 +354,7 @@ static struct snd_akm4xxx akm_ews88mt = {
}
};
-static struct snd_ak4xxx_private akm_ews88mt_priv = {
+static const struct snd_ak4xxx_private akm_ews88mt_priv = {
.caddr = 2,
.cif = 1, /* CIF high */
.data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -366,7 +366,7 @@ static struct snd_ak4xxx_private akm_ews88mt_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_ewx2496 = {
+static const struct snd_akm4xxx akm_ewx2496 = {
.num_adcs = 2,
.num_dacs = 2,
.type = SND_AK4524,
@@ -375,7 +375,7 @@ static struct snd_akm4xxx akm_ewx2496 = {
}
};
-static struct snd_ak4xxx_private akm_ewx2496_priv = {
+static const struct snd_ak4xxx_private akm_ewx2496_priv = {
.caddr = 2,
.cif = 1, /* CIF high */
.data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -387,7 +387,7 @@ static struct snd_ak4xxx_private akm_ewx2496_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_6fire = {
+static const struct snd_akm4xxx akm_6fire = {
.num_adcs = 6,
.num_dacs = 6,
.type = SND_AK4524,
@@ -396,7 +396,7 @@ static struct snd_akm4xxx akm_6fire = {
}
};
-static struct snd_ak4xxx_private akm_6fire_priv = {
+static const struct snd_ak4xxx_private akm_6fire_priv = {
.caddr = 2,
.cif = 1, /* CIF high */
.data_mask = ICE1712_6FIRE_SERIAL_DATA,
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index a40001c1d9e8..fa301d31745b 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -166,7 +166,7 @@ static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
mutex_unlock(&ice->gpio_mutex);
}
-static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
+static int hoontech_init(struct snd_ice1712 *ice, bool staudio)
{
struct hoontech_spec *spec;
int box, chn;
@@ -203,7 +203,10 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
ICE1712_STDSP24_3_INSEL(spec->boxbits, 0);
/* let's go - activate only functions in first box */
- spec->config = 0;
+ if (staudio)
+ spec->config = ICE1712_STDSP24_MUTE;
+ else
+ spec->config = 0;
/* ICE1712_STDSP24_MUTE |
ICE1712_STDSP24_INSEL |
ICE1712_STDSP24_DAREAR; */
@@ -226,9 +229,16 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
ICE1712_STDSP24_BOX_CHN4 |
ICE1712_STDSP24_BOX_MIDI1 |
ICE1712_STDSP24_BOX_MIDI2;
- spec->boxconfig[1] =
- spec->boxconfig[2] =
- spec->boxconfig[3] = 0;
+ if (staudio) {
+ spec->boxconfig[1] =
+ spec->boxconfig[2] =
+ spec->boxconfig[3] = spec->boxconfig[0];
+ } else {
+ spec->boxconfig[1] =
+ spec->boxconfig[2] =
+ spec->boxconfig[3] = 0;
+ }
+
snd_ice1712_stdsp24_darear(ice,
(spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
snd_ice1712_stdsp24_mute(ice,
@@ -248,6 +258,16 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
return 0;
}
+static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
+{
+ return hoontech_init(ice, false);
+}
+
+static int snd_ice1712_staudio_init(struct snd_ice1712 *ice)
+{
+ return hoontech_init(ice, true);
+}
+
/*
* AK4524 access
*/
@@ -269,7 +289,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
static int snd_ice1712_value_init(struct snd_ice1712 *ice)
{
/* Hoontech STDSP24 with modified hardware */
- static struct snd_akm4xxx akm_stdsp24_mv = {
+ static const struct snd_akm4xxx akm_stdsp24_mv = {
.num_adcs = 2,
.num_dacs = 2,
.type = SND_AK4524,
@@ -278,7 +298,7 @@ static int snd_ice1712_value_init(struct snd_ice1712 *ice)
}
};
- static struct snd_ak4xxx_private akm_stdsp24_mv_priv = {
+ static const struct snd_ak4xxx_private akm_stdsp24_mv_priv = {
.caddr = 2,
.cif = 1, /* CIF high */
.data_mask = ICE1712_STDSP24_SERIAL_DATA,
@@ -351,5 +371,14 @@ struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = {
.model = "ez8",
.chip_init = snd_ice1712_ez8_init,
},
+ {
+ /* STAudio ADCIII has the same SSID as Hoontech StA DSP24,
+ * thus identified only via the explicit model option
+ */
+ .subvendor = ICE1712_SUBDEVICE_STAUDIO_ADCIII, /* a dummy id */
+ .name = "STAudio ADCIII",
+ .model = "staudio",
+ .chip_init = snd_ice1712_staudio_init,
+ },
{ } /* terminator */
};
diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h
index cc1da1e69ad1..7f94943392ce 100644
--- a/sound/pci/ice1712/hoontech.h
+++ b/sound/pci/ice1712/hoontech.h
@@ -34,6 +34,7 @@
#define ICE1712_SUBDEVICE_STDSP24_VALUE 0x00010010 /* A dummy id for Hoontech SoundTrack Audio DSP 24 Value */
#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */
#define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */
+#define ICE1712_SUBDEVICE_STAUDIO_ADCIII 0x00010002 /* A dummy id for STAudio ADCIII */
extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 5bb146703738..0dbaccf61f33 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -282,7 +282,7 @@ static const struct snd_akm4xxx_dac_channel juli_dac[] = {
};
-static struct snd_akm4xxx akm_juli_dac = {
+static const struct snd_akm4xxx akm_juli_dac = {
.type = SND_AK4358,
.num_dacs = 8, /* DAC1 - analog out
DAC2 - analog in monitor
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index e9ca89c9174b..67fbb28bf033 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -102,13 +102,13 @@ static const unsigned char wm_vol[256] = {
#define WM_VOL_MAX (sizeof(wm_vol) - 1)
#define WM_VOL_MUTE 0x8000
-static struct snd_akm4xxx akm_phase22 = {
+static const struct snd_akm4xxx akm_phase22 = {
.type = SND_AK4524,
.num_dacs = 2,
.num_adcs = 2,
};
-static struct snd_ak4xxx_private akm_phase22_priv = {
+static const struct snd_ak4xxx_private akm_phase22_priv = {
.caddr = 2,
.cif = 1,
.data_mask = 1 << 4,
diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c
index f1b3732cc6d2..d145b5eb7ff8 100644
--- a/sound/pci/ice1712/quartet.c
+++ b/sound/pci/ice1712/quartet.c
@@ -386,7 +386,7 @@ static const struct snd_akm4xxx_adc_channel qtet_adc[] = {
AK_CONTROL(PCM_34_CAPTURE_VOLUME, 2),
};
-static struct snd_akm4xxx akm_qtet_dac = {
+static const struct snd_akm4xxx akm_qtet_dac = {
.type = SND_AK4620,
.num_dacs = 4, /* DAC1 - Output 12
*/
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index 1d81ae677573..6669c389f336 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -235,7 +235,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
},
};
-static struct snd_akm4xxx akm_revo_front = {
+static const struct snd_akm4xxx akm_revo_front = {
.type = SND_AK4381,
.num_dacs = 2,
.ops = {
@@ -244,7 +244,7 @@ static struct snd_akm4xxx akm_revo_front = {
.dac_info = revo71_front,
};
-static struct snd_ak4xxx_private akm_revo_front_priv = {
+static const struct snd_ak4xxx_private akm_revo_front_priv = {
.caddr = 1,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -256,7 +256,7 @@ static struct snd_ak4xxx_private akm_revo_front_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_revo_surround = {
+static const struct snd_akm4xxx akm_revo_surround = {
.type = SND_AK4355,
.idx_offset = 1,
.num_dacs = 6,
@@ -266,7 +266,7 @@ static struct snd_akm4xxx akm_revo_surround = {
.dac_info = revo71_surround,
};
-static struct snd_ak4xxx_private akm_revo_surround_priv = {
+static const struct snd_ak4xxx_private akm_revo_surround_priv = {
.caddr = 3,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -278,7 +278,7 @@ static struct snd_ak4xxx_private akm_revo_surround_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_revo51 = {
+static const struct snd_akm4xxx akm_revo51 = {
.type = SND_AK4358,
.num_dacs = 8,
.ops = {
@@ -287,7 +287,7 @@ static struct snd_akm4xxx akm_revo51 = {
.dac_info = revo51_dac,
};
-static struct snd_ak4xxx_private akm_revo51_priv = {
+static const struct snd_ak4xxx_private akm_revo51_priv = {
.caddr = 2,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -299,13 +299,13 @@ static struct snd_ak4xxx_private akm_revo51_priv = {
.mask_flags = 0,
};
-static struct snd_akm4xxx akm_revo51_adc = {
+static const struct snd_akm4xxx akm_revo51_adc = {
.type = SND_AK5365,
.num_adcs = 2,
.adc_info = revo51_adc,
};
-static struct snd_ak4xxx_private akm_revo51_adc_priv = {
+static const struct snd_ak4xxx_private akm_revo51_adc_priv = {
.caddr = 2,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
@@ -346,7 +346,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
AK_DAC("PCM Playback Volume", 2)
};
-static struct snd_akm4xxx akm_ap192 = {
+static const struct snd_akm4xxx akm_ap192 = {
.type = SND_AK4358,
.num_dacs = 2,
.ops = {
@@ -355,7 +355,7 @@ static struct snd_akm4xxx akm_ap192 = {
.dac_info = ap192_dac,
};
-static struct snd_ak4xxx_private akm_ap192_priv = {
+static const struct snd_ak4xxx_private akm_ap192_priv = {
.caddr = 2,
.cif = 0,
.data_mask = VT1724_REVO_CDOUT,
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index a8d7092e93dd..4c24346340f4 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1115,7 +1115,7 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs
return bytes_to_frames(substream->runtime, ptr);
}
-static struct snd_pcm_hardware snd_intel8x0_stream =
+static const struct snd_pcm_hardware snd_intel8x0_stream =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1367,7 +1367,7 @@ static int snd_intel8x0_ali_spdifout_close(struct snd_pcm_substream *substream)
}
#endif
-static struct snd_pcm_ops snd_intel8x0_playback_ops = {
+static const struct snd_pcm_ops snd_intel8x0_playback_ops = {
.open = snd_intel8x0_playback_open,
.close = snd_intel8x0_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1378,7 +1378,7 @@ static struct snd_pcm_ops snd_intel8x0_playback_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_capture_ops = {
+static const struct snd_pcm_ops snd_intel8x0_capture_ops = {
.open = snd_intel8x0_capture_open,
.close = snd_intel8x0_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1389,7 +1389,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = {
+static const struct snd_pcm_ops snd_intel8x0_capture_mic_ops = {
.open = snd_intel8x0_mic_open,
.close = snd_intel8x0_mic_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1400,7 +1400,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = {
+static const struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = {
.open = snd_intel8x0_mic2_open,
.close = snd_intel8x0_mic2_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1411,7 +1411,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_capture2_ops = {
+static const struct snd_pcm_ops snd_intel8x0_capture2_ops = {
.open = snd_intel8x0_capture2_open,
.close = snd_intel8x0_capture2_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1422,7 +1422,7 @@ static struct snd_pcm_ops snd_intel8x0_capture2_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_spdif_ops = {
+static const struct snd_pcm_ops snd_intel8x0_spdif_ops = {
.open = snd_intel8x0_spdif_open,
.close = snd_intel8x0_spdif_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1433,7 +1433,7 @@ static struct snd_pcm_ops snd_intel8x0_spdif_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = {
+static const struct snd_pcm_ops snd_intel8x0_ali_playback_ops = {
.open = snd_intel8x0_playback_open,
.close = snd_intel8x0_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1444,7 +1444,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_ali_capture_ops = {
+static const struct snd_pcm_ops snd_intel8x0_ali_capture_ops = {
.open = snd_intel8x0_capture_open,
.close = snd_intel8x0_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1455,7 +1455,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_capture_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = {
+static const struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = {
.open = snd_intel8x0_mic_open,
.close = snd_intel8x0_mic_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1466,7 +1466,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = {
+static const struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = {
.open = snd_intel8x0_ali_ac97spdifout_open,
.close = snd_intel8x0_ali_ac97spdifout_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -1503,8 +1503,8 @@ static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = {
struct ich_pcm_table {
char *suffix;
- struct snd_pcm_ops *playback_ops;
- struct snd_pcm_ops *capture_ops;
+ const struct snd_pcm_ops *playback_ops;
+ const struct snd_pcm_ops *capture_ops;
size_t prealloc_size;
size_t prealloc_max_size;
int ac97_idx;
@@ -1721,7 +1721,7 @@ static void snd_intel8x0_mixer_free_ac97(struct snd_ac97 *ac97)
chip->ac97[ac97->num] = NULL;
}
-static struct ac97_pcm ac97_pcm_defs[] = {
+static const struct ac97_pcm ac97_pcm_defs[] = {
/* front PCM */
{
.exclusive = 1,
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 18ff668ce7a5..3a4769a97d29 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -611,7 +611,7 @@ static int snd_intel8x0m_pcm_prepare(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_hardware snd_intel8x0m_stream =
+static const struct snd_pcm_hardware snd_intel8x0m_stream =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -685,7 +685,7 @@ static int snd_intel8x0m_capture_close(struct snd_pcm_substream *substream)
}
-static struct snd_pcm_ops snd_intel8x0m_playback_ops = {
+static const struct snd_pcm_ops snd_intel8x0m_playback_ops = {
.open = snd_intel8x0m_playback_open,
.close = snd_intel8x0m_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -696,7 +696,7 @@ static struct snd_pcm_ops snd_intel8x0m_playback_ops = {
.pointer = snd_intel8x0m_pcm_pointer,
};
-static struct snd_pcm_ops snd_intel8x0m_capture_ops = {
+static const struct snd_pcm_ops snd_intel8x0m_capture_ops = {
.open = snd_intel8x0m_capture_open,
.close = snd_intel8x0m_capture_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -710,8 +710,8 @@ static struct snd_pcm_ops snd_intel8x0m_capture_ops = {
struct ich_pcm_table {
char *suffix;
- struct snd_pcm_ops *playback_ops;
- struct snd_pcm_ops *capture_ops;
+ const struct snd_pcm_ops *playback_ops;
+ const struct snd_pcm_ops *capture_ops;
size_t prealloc_size;
size_t prealloc_max_size;
int ac97_idx;
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index b28fe4914d6b..04cd71c74e5c 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -1231,7 +1231,7 @@ static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212)
return 0;
}
-static struct snd_pcm_hardware snd_korg1212_playback_info =
+static const struct snd_pcm_hardware snd_korg1212_playback_info =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -1252,7 +1252,7 @@ static struct snd_pcm_hardware snd_korg1212_playback_info =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_korg1212_capture_info =
+static const struct snd_pcm_hardware snd_korg1212_capture_info =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c
index 1268ba329016..310b26a756c9 100644
--- a/sound/pci/lola/lola_pcm.c
+++ b/sound/pci/lola/lola_pcm.c
@@ -197,7 +197,7 @@ static void lola_stream_reset(struct lola *chip, struct lola_stream *str)
}
}
-static struct snd_pcm_hardware lola_pcm_hw = {
+static const struct snd_pcm_hardware lola_pcm_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index f9c3e86d55d5..9655b08a1c52 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -77,7 +77,7 @@ MODULE_DEVICE_TABLE(pci, snd_lx6464es_ids);
/* alsa callbacks */
-static struct snd_pcm_hardware lx_caps = {
+static const struct snd_pcm_hardware lx_caps = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index cafea6dc5c01..97ac80af4447 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1681,7 +1681,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
/*
*/
-static struct snd_pcm_hardware snd_m3_playback =
+static const struct snd_pcm_hardware snd_m3_playback =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -1702,7 +1702,7 @@ static struct snd_pcm_hardware snd_m3_playback =
.periods_max = 1024,
};
-static struct snd_pcm_hardware snd_m3_capture =
+static const struct snd_pcm_hardware snd_m3_capture =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 80d439944cb5..a74f1ad7e7b8 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -675,7 +675,7 @@ static int snd_mixart_hw_free(struct snd_pcm_substream *subs)
/*
* TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
*/
-static struct snd_pcm_hardware snd_mixart_analog_caps =
+static const struct snd_pcm_hardware snd_mixart_analog_caps =
{
.info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -696,7 +696,7 @@ static struct snd_pcm_hardware snd_mixart_analog_caps =
.periods_max = (32*1024/256),
};
-static struct snd_pcm_hardware snd_mixart_digital_caps =
+static const struct snd_pcm_hardware snd_mixart_digital_caps =
{
.info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -1052,10 +1052,8 @@ static int snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int
};
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (! chip) {
- dev_err(card->dev, "cannot allocate chip\n");
+ if (!chip)
return -ENOMEM;
- }
chip->card = card;
chip->chip_idx = idx;
@@ -1313,9 +1311,6 @@ static int snd_mixart_probe(struct pci_dev *pci,
}
mgr->irq = pci->irq;
- sprintf(mgr->shortname, "Digigram miXart");
- sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, irq %i", mgr->shortname, mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq);
-
/* init mailbox */
mgr->msg_fifo_readptr = 0;
mgr->msg_fifo_writeptr = 0;
@@ -1350,8 +1345,11 @@ static int snd_mixart_probe(struct pci_dev *pci,
}
strcpy(card->driver, CARD_NAME);
- sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i);
- sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
+ snprintf(card->shortname, sizeof(card->shortname),
+ "Digigram miXart [PCM #%d]", i);
+ snprintf(card->longname, sizeof(card->longname),
+ "Digigram miXart at 0x%lx & 0x%lx, irq %i [PCM #%d]",
+ mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq, i);
if ((err = snd_mixart_create(mgr, card, i)) < 0) {
snd_card_free(card);
diff --git a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h
index 426743871540..69b3ece099ad 100644
--- a/sound/pci/mixart/mixart.h
+++ b/sound/pci/mixart/mixart.h
@@ -74,10 +74,6 @@ struct mixart_mgr {
/* memory-maps */
struct mem_area mem[2];
- /* share the name */
- char shortname[32]; /* short name of this soundcard */
- char longname[80]; /* name of this soundcard */
-
/* one and only blocking message or notification may be pending */
u32 pending_event;
wait_queue_head_t msg_sleep;
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 0ef8054c3936..b97f4ea6b56c 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1271,7 +1271,7 @@ snd_nm256_ac97_write(struct snd_ac97 *ac97,
}
/* static resolution table */
-static struct snd_ac97_res_table nm256_res_table[] = {
+static const struct snd_ac97_res_table nm256_res_table[] = {
{ AC97_MASTER, 0x1f1f },
{ AC97_HEADPHONE, 0x1f1f },
{ AC97_MASTER_MONO, 0x001f },
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index bb7eee9d0c2b..f9ae72f28ddc 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -986,7 +986,7 @@ static int pcxhr_hw_free(struct snd_pcm_substream *subs)
/*
* CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
*/
-static struct snd_pcm_hardware pcxhr_caps =
+static const struct snd_pcm_hardware pcxhr_caps =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -1165,7 +1165,7 @@ int pcxhr_create_pcm(struct snd_pcxhr *chip)
struct snd_pcm *pcm;
char name[32];
- sprintf(name, "pcxhr %d", chip->chip_idx);
+ snprintf(name, sizeof(name), "pcxhr %d", chip->chip_idx);
if ((err = snd_pcm_new(chip->card, name, 0,
chip->nb_streams_play,
chip->nb_streams_capt, &pcm)) < 0) {
@@ -1215,10 +1215,8 @@ static int pcxhr_create(struct pcxhr_mgr *mgr,
};
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (! chip) {
- dev_err(card->dev, "cannot allocate chip\n");
+ if (!chip)
return -ENOMEM;
- }
chip->card = card;
chip->chip_idx = idx;
@@ -1252,7 +1250,7 @@ static void pcxhr_proc_info(struct snd_info_entry *entry,
struct snd_pcxhr *chip = entry->private_data;
struct pcxhr_mgr *mgr = chip->mgr;
- snd_iprintf(buffer, "\n%s\n", mgr->longname);
+ snd_iprintf(buffer, "\n%s\n", mgr->name);
/* stats available when embedded DSP is running */
if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
@@ -1339,7 +1337,7 @@ static void pcxhr_proc_sync(struct snd_info_entry *entry,
max_clock = PCXHR_CLOCK_TYPE_MAX;
}
- snd_iprintf(buffer, "\n%s\n", mgr->longname);
+ snd_iprintf(buffer, "\n%s\n", mgr->name);
snd_iprintf(buffer, "Current Sample Clock\t: %s\n",
texts[mgr->cur_clock_type]);
snd_iprintf(buffer, "Current Sample Rate\t= %d\n",
@@ -1597,10 +1595,9 @@ static int pcxhr_probe(struct pci_dev *pci,
}
mgr->irq = pci->irq;
- sprintf(mgr->shortname, "Digigram %s", card_name);
- sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i",
- mgr->shortname,
- mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
+ snprintf(mgr->name, sizeof(mgr->name),
+ "Digigram at 0x%lx & 0x%lx, 0x%lx irq %i",
+ mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
/* ISR lock */
mutex_init(&mgr->lock);
@@ -1644,8 +1641,10 @@ static int pcxhr_probe(struct pci_dev *pci,
}
strcpy(card->driver, DRIVER_NAME);
- sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i);
- sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
+ snprintf(card->shortname, sizeof(card->shortname),
+ "Digigram [PCM #%d]", i);
+ snprintf(card->longname, sizeof(card->longname),
+ "%s [PCM #%d]", mgr->name, i);
if ((err = pcxhr_create(mgr, card, i)) < 0) {
snd_card_free(card);
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h
index 9e39e509a3ef..d799cbd37301 100644
--- a/sound/pci/pcxhr/pcxhr.h
+++ b/sound/pci/pcxhr/pcxhr.h
@@ -75,8 +75,7 @@ struct pcxhr_mgr {
unsigned long port[3];
/* share the name */
- char shortname[32]; /* short name of this soundcard */
- char longname[96]; /* name of this soundcard */
+ char name[40]; /* name of this soundcard */
struct pcxhr_rmh *prmh;
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index 36875df30dbf..d9a1c6c50a87 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -185,7 +185,7 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
return changed;
}
-static struct snd_kcontrol_new pcxhr_control_analog_level = {
+static const struct snd_kcontrol_new pcxhr_control_analog_level = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -409,7 +409,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
return changed;
}
-static struct snd_kcontrol_new snd_pcxhr_pcm_vol =
+static const struct snd_kcontrol_new snd_pcxhr_pcm_vol =
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index f067c76d77f8..44f3b48d47b1 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1315,7 +1315,7 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)
return 0;
}
-static struct snd_pcm_hardware snd_riptide_playback = {
+static const struct snd_pcm_hardware snd_riptide_playback = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
@@ -1334,7 +1334,7 @@ static struct snd_pcm_hardware snd_riptide_playback = {
.periods_max = 64,
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_riptide_capture = {
+static const struct snd_pcm_hardware snd_riptide_capture = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index e4cdef94e4a2..f0906ba416d4 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -314,7 +314,7 @@ static int snd_rme32_capture_copy_kernel(struct snd_pcm_substream *substream,
/*
* SPDIF I/O capabilities (half-duplex mode)
*/
-static struct snd_pcm_hardware snd_rme32_spdif_info = {
+static const struct snd_pcm_hardware snd_rme32_spdif_info = {
.info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -340,7 +340,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_info = {
/*
* ADAT I/O capabilities (half-duplex mode)
*/
-static struct snd_pcm_hardware snd_rme32_adat_info =
+static const struct snd_pcm_hardware snd_rme32_adat_info =
{
.info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -365,7 +365,7 @@ static struct snd_pcm_hardware snd_rme32_adat_info =
/*
* SPDIF I/O capabilities (full-duplex mode)
*/
-static struct snd_pcm_hardware snd_rme32_spdif_fd_info = {
+static const struct snd_pcm_hardware snd_rme32_spdif_fd_info = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -391,7 +391,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_fd_info = {
/*
* ADAT I/O capabilities (full-duplex mode)
*/
-static struct snd_pcm_hardware snd_rme32_adat_fd_info =
+static const struct snd_pcm_hardware snd_rme32_adat_fd_info =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 2e19ba55e754..dcfa4d7a73e2 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -384,7 +384,7 @@ snd_rme96_capture_copy_kernel(struct snd_pcm_substream *substream,
/*
* Digital output capabilities (S/PDIF)
*/
-static struct snd_pcm_hardware snd_rme96_playback_spdif_info =
+static const struct snd_pcm_hardware snd_rme96_playback_spdif_info =
{
.info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -415,7 +415,7 @@ static struct snd_pcm_hardware snd_rme96_playback_spdif_info =
/*
* Digital input capabilities (S/PDIF)
*/
-static struct snd_pcm_hardware snd_rme96_capture_spdif_info =
+static const struct snd_pcm_hardware snd_rme96_capture_spdif_info =
{
.info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -446,7 +446,7 @@ static struct snd_pcm_hardware snd_rme96_capture_spdif_info =
/*
* Digital output capabilities (ADAT)
*/
-static struct snd_pcm_hardware snd_rme96_playback_adat_info =
+static const struct snd_pcm_hardware snd_rme96_playback_adat_info =
{
.info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -473,7 +473,7 @@ static struct snd_pcm_hardware snd_rme96_playback_adat_info =
/*
* Digital input capabilities (ADAT)
*/
-static struct snd_pcm_hardware snd_rme96_capture_adat_info =
+static const struct snd_pcm_hardware snd_rme96_capture_adat_info =
{
.info = (SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -1199,7 +1199,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
spin_lock_irq(&rme96->lock);
- if (rme96->playback_substream != NULL) {
+ if (rme96->playback_substream) {
spin_unlock_irq(&rme96->lock);
return -EBUSY;
}
@@ -1248,7 +1248,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
}
spin_lock_irq(&rme96->lock);
- if (rme96->capture_substream != NULL) {
+ if (rme96->capture_substream) {
spin_unlock_irq(&rme96->lock);
return -EBUSY;
}
@@ -1268,7 +1268,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
spin_lock_irq(&rme96->lock);
- if (rme96->playback_substream != NULL) {
+ if (rme96->playback_substream) {
spin_unlock_irq(&rme96->lock);
return -EBUSY;
}
@@ -1315,7 +1315,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
}
spin_lock_irq(&rme96->lock);
- if (rme96->capture_substream != NULL) {
+ if (rme96->capture_substream) {
spin_unlock_irq(&rme96->lock);
return -EBUSY;
}
@@ -1578,9 +1578,9 @@ snd_rme96_free(void *private_data)
{
struct rme96 *rme96 = (struct rme96 *)private_data;
- if (rme96 == NULL) {
+ if (!rme96)
return;
- }
+
if (rme96->irq >= 0) {
snd_rme96_trigger(rme96, RME96_STOP_BOTH);
rme96->areg &= ~RME96_AR_DAC_EN;
@@ -2481,25 +2481,20 @@ snd_rme96_probe(struct pci_dev *pci,
rme96 = card->private_data;
rme96->card = card;
rme96->pci = pci;
- if ((err = snd_rme96_create(rme96)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_rme96_create(rme96);
+ if (err)
+ goto free_card;
#ifdef CONFIG_PM_SLEEP
rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE);
if (!rme96->playback_suspend_buffer) {
- dev_err(card->dev,
- "Failed to allocate playback suspend buffer!\n");
- snd_card_free(card);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto free_card;
}
rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE);
if (!rme96->capture_suspend_buffer) {
- dev_err(card->dev,
- "Failed to allocate capture suspend buffer!\n");
- snd_card_free(card);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto free_card;
}
#endif
@@ -2525,14 +2520,16 @@ snd_rme96_probe(struct pci_dev *pci,
}
sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname,
rme96->port, rme96->irq);
-
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_card_register(card);
+ if (err)
+ goto free_card;
+
pci_set_drvdata(pci, card);
dev++;
return 0;
+free_card:
+ snd_card_free(card);
+ return err;
}
static void snd_rme96_remove(struct pci_dev *pci)
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index fe36d44d16c6..0ff41f9ab434 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -4211,7 +4211,7 @@ static int snd_hdsp_prepare(struct snd_pcm_substream *substream)
return result;
}
-static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
+static const struct snd_pcm_hardware snd_hdsp_playback_subinfo =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -4241,7 +4241,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
.fifo_size = 0
};
-static struct snd_pcm_hardware snd_hdsp_capture_subinfo =
+static const struct snd_pcm_hardware snd_hdsp_capture_subinfo =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -5381,17 +5381,16 @@ static int snd_hdsp_probe(struct pci_dev *pci,
card->private_free = snd_hdsp_card_free;
hdsp->dev = dev;
hdsp->pci = pci;
-
- if ((err = snd_hdsp_create(card, hdsp)) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_hdsp_create(card, hdsp);
+ if (err)
+ goto free_card;
strcpy(card->shortname, "Hammerfall DSP");
sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name,
hdsp->port, hdsp->irq);
-
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err) {
+free_card:
snd_card_free(card);
return err;
}
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 254c3d040118..25284d8d9758 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1521,7 +1521,7 @@ static void hdspm_silence_playback(struct hdspm *hdspm)
int n = hdspm->period_bytes;
void *buf = hdspm->playback_buffer;
- if (buf == NULL)
+ if (!buf)
return;
for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
@@ -2061,7 +2061,7 @@ static int snd_hdspm_create_midi(struct snd_card *card,
struct hdspm *hdspm, int id)
{
int err;
- char buf[32];
+ char buf[64];
hdspm->midi[id].id = id;
hdspm->midi[id].hdspm = hdspm;
@@ -2120,19 +2120,23 @@ static int snd_hdspm_create_midi(struct snd_card *card,
if ((id < 2) || ((2 == id) && ((MADI == hdspm->io_type) ||
(MADIface == hdspm->io_type)))) {
if ((id == 0) && (MADIface == hdspm->io_type)) {
- sprintf(buf, "%s MIDIoverMADI", card->shortname);
+ snprintf(buf, sizeof(buf), "%s MIDIoverMADI",
+ card->shortname);
} else if ((id == 2) && (MADI == hdspm->io_type)) {
- sprintf(buf, "%s MIDIoverMADI", card->shortname);
+ snprintf(buf, sizeof(buf), "%s MIDIoverMADI",
+ card->shortname);
} else {
- sprintf(buf, "%s MIDI %d", card->shortname, id+1);
+ snprintf(buf, sizeof(buf), "%s MIDI %d",
+ card->shortname, id+1);
}
err = snd_rawmidi_new(card, buf, id, 1, 1,
&hdspm->midi[id].rmidi);
if (err < 0)
return err;
- sprintf(hdspm->midi[id].rmidi->name, "%s MIDI %d",
- card->id, id+1);
+ snprintf(hdspm->midi[id].rmidi->name,
+ sizeof(hdspm->midi[id].rmidi->name),
+ "%s MIDI %d", card->id, id+1);
hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
@@ -2148,14 +2152,16 @@ static int snd_hdspm_create_midi(struct snd_card *card,
SNDRV_RAWMIDI_INFO_DUPLEX;
} else {
/* TCO MTC, read only */
- sprintf(buf, "%s MTC %d", card->shortname, id+1);
+ snprintf(buf, sizeof(buf), "%s MTC %d",
+ card->shortname, id+1);
err = snd_rawmidi_new(card, buf, id, 1, 1,
&hdspm->midi[id].rmidi);
if (err < 0)
return err;
- sprintf(hdspm->midi[id].rmidi->name,
- "%s MTC %d", card->id, id+1);
+ snprintf(hdspm->midi[id].rmidi->name,
+ sizeof(hdspm->midi[id].rmidi->name),
+ "%s MTC %d", card->id, id+1);
hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
snd_rawmidi_set_ops(hdspm->midi[id].rmidi,
@@ -4700,7 +4706,7 @@ static int snd_hdspm_create_controls(struct snd_card *card,
break;
}
- if (NULL != list) {
+ if (list) {
for (idx = 0; idx < limit; idx++) {
err = snd_ctl_add(card,
snd_ctl_new1(&list[idx], hdspm));
@@ -6063,13 +6069,13 @@ static int snd_hdspm_open(struct snd_pcm_substream *substream)
snd_hdspm_capture_subinfo;
if (playback) {
- if (hdspm->capture_substream == NULL)
+ if (!hdspm->capture_substream)
hdspm_stop_audio(hdspm);
hdspm->playback_pid = current->pid;
hdspm->playback_substream = substream;
} else {
- if (hdspm->playback_substream == NULL)
+ if (!hdspm->playback_substream)
hdspm_stop_audio(hdspm);
hdspm->capture_pid = current->pid;
@@ -6215,7 +6221,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
}
levels->status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
- s = copy_to_user(argp, levels, sizeof(struct hdspm_peak_rms));
+ s = copy_to_user(argp, levels, sizeof(*levels));
if (0 != s) {
/* dev_err(hdspm->card->dev, "copy_to_user(.., .., %lu): %lu
[Levels]\n", sizeof(struct hdspm_peak_rms), s);
@@ -6260,7 +6266,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
ltc.input_format = no_video;
}
- s = copy_to_user(argp, &ltc, sizeof(struct hdspm_ltc));
+ s = copy_to_user(argp, &ltc, sizeof(ltc));
if (0 != s) {
/*
dev_err(hdspm->card->dev, "copy_to_user(.., .., %lu): %lu [LTC]\n", sizeof(struct hdspm_ltc), s); */
@@ -6351,7 +6357,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
if (copy_from_user(&mixer, argp, sizeof(mixer)))
return -EFAULT;
if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer,
- sizeof(struct hdspm_mixer)))
+ sizeof(*mixer.mixer)))
return -EFAULT;
break;
@@ -6630,14 +6636,10 @@ static int snd_hdspm_create(struct snd_card *card,
hdspm->irq = pci->irq;
dev_dbg(card->dev, "kmalloc Mixer memory of %zd Bytes\n",
- sizeof(struct hdspm_mixer));
- hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL);
- if (!hdspm->mixer) {
- dev_err(card->dev,
- "unable to kmalloc Mixer memory of %d Bytes\n",
- (int)sizeof(struct hdspm_mixer));
+ sizeof(*hdspm->mixer));
+ hdspm->mixer = kzalloc(sizeof(*hdspm->mixer), GFP_KERNEL);
+ if (!hdspm->mixer)
return -ENOMEM;
- }
hdspm->port_names_in = NULL;
hdspm->port_names_out = NULL;
@@ -6772,11 +6774,10 @@ static int snd_hdspm_create(struct snd_card *card,
if (hdspm_read(hdspm, HDSPM_statusRegister2) &
HDSPM_s2_tco_detect) {
hdspm->midiPorts++;
- hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
- GFP_KERNEL);
- if (NULL != hdspm->tco) {
+ hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL);
+ if (hdspm->tco)
hdspm_tco_write(hdspm);
- }
+
dev_info(card->dev, "AIO/RayDAT TCO module found\n");
} else {
hdspm->tco = NULL;
@@ -6787,11 +6788,10 @@ static int snd_hdspm_create(struct snd_card *card,
case AES32:
if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) {
hdspm->midiPorts++;
- hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
- GFP_KERNEL);
- if (NULL != hdspm->tco) {
+ hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL);
+ if (hdspm->tco)
hdspm_tco_write(hdspm);
- }
+
dev_info(card->dev, "MADI/AES TCO module found\n");
} else {
hdspm->tco = NULL;
@@ -6868,8 +6868,9 @@ static int snd_hdspm_create(struct snd_card *card,
* this case, we don't set card->id to avoid collisions
* when running with multiple cards.
*/
- if (NULL == id[hdspm->dev] && hdspm->serial != 0xFFFFFF) {
- sprintf(card->id, "HDSPMx%06x", hdspm->serial);
+ if (!id[hdspm->dev] && hdspm->serial != 0xFFFFFF) {
+ snprintf(card->id, sizeof(card->id),
+ "HDSPMx%06x", hdspm->serial);
snd_card_set_id(card, card->id);
}
}
@@ -6938,7 +6939,7 @@ static int snd_hdspm_probe(struct pci_dev *pci,
}
err = snd_card_new(&pci->dev, index[dev], id[dev],
- THIS_MODULE, sizeof(struct hdspm), &card);
+ THIS_MODULE, sizeof(*hdspm), &card);
if (err < 0)
return err;
@@ -6954,17 +6955,18 @@ static int snd_hdspm_probe(struct pci_dev *pci,
}
if (hdspm->io_type != MADIface) {
- sprintf(card->shortname, "%s_%x",
- hdspm->card_name,
- hdspm->serial);
- sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d",
- hdspm->card_name,
- hdspm->serial,
- hdspm->port, hdspm->irq);
+ snprintf(card->shortname, sizeof(card->shortname), "%s_%x",
+ hdspm->card_name, hdspm->serial);
+ snprintf(card->longname, sizeof(card->longname),
+ "%s S/N 0x%x at 0x%lx, irq %d",
+ hdspm->card_name, hdspm->serial,
+ hdspm->port, hdspm->irq);
} else {
- sprintf(card->shortname, "%s", hdspm->card_name);
- sprintf(card->longname, "%s at 0x%lx, irq %d",
- hdspm->card_name, hdspm->port, hdspm->irq);
+ snprintf(card->shortname, sizeof(card->shortname), "%s",
+ hdspm->card_name);
+ snprintf(card->longname, sizeof(card->longname),
+ "%s at 0x%lx, irq %d",
+ hdspm->card_name, hdspm->port, hdspm->irq);
}
err = snd_card_register(card);
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 150d08898db8..df648b1d9217 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -2181,7 +2181,7 @@ static int snd_rme9652_prepare(struct snd_pcm_substream *substream)
return result;
}
-static struct snd_pcm_hardware snd_rme9652_playback_subinfo =
+static const struct snd_pcm_hardware snd_rme9652_playback_subinfo =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -2205,7 +2205,7 @@ static struct snd_pcm_hardware snd_rme9652_playback_subinfo =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_rme9652_capture_subinfo =
+static const struct snd_pcm_hardware snd_rme9652_capture_subinfo =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -2618,19 +2618,17 @@ static int snd_rme9652_probe(struct pci_dev *pci,
card->private_free = snd_rme9652_card_free;
rme9652->dev = dev;
rme9652->pci = pci;
-
- if ((err = snd_rme9652_create(card, rme9652, precise_ptr[dev])) < 0) {
- snd_card_free(card);
- return err;
- }
+ err = snd_rme9652_create(card, rme9652, precise_ptr[dev]);
+ if (err)
+ goto free_card;
strcpy(card->shortname, rme9652->card_name);
sprintf(card->longname, "%s at 0x%lx, irq %d",
card->shortname, rme9652->port, rme9652->irq);
-
-
- if ((err = snd_card_register(card)) < 0) {
+ err = snd_card_register(card);
+ if (err) {
+free_card:
snd_card_free(card);
return err;
}
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index f3860b850210..964acf302479 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -159,7 +159,7 @@ struct sis7019 {
* We'll add a constraint upon open that limits the period and buffer sample
* size to values that are legal for the hardware.
*/
-static struct snd_pcm_hardware sis_playback_hw_info = {
+static const struct snd_pcm_hardware sis_playback_hw_info = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -180,7 +180,7 @@ static struct snd_pcm_hardware sis_playback_hw_info = {
.periods_max = (0xfff9 / 9),
};
-static struct snd_pcm_hardware sis_capture_hw_info = {
+static const struct snd_pcm_hardware sis_capture_hw_info = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -872,7 +872,7 @@ static int sis_pcm_capture_prepare(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_ops sis_playback_ops = {
+static const struct snd_pcm_ops sis_playback_ops = {
.open = sis_playback_open,
.close = sis_substream_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -883,7 +883,7 @@ static struct snd_pcm_ops sis_playback_ops = {
.pointer = sis_pcm_pointer,
};
-static struct snd_pcm_ops sis_capture_ops = {
+static const struct snd_pcm_ops sis_capture_ops = {
.open = sis_capture_open,
.close = sis_substream_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 784d762f18a7..a8abb15e3c3a 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -776,7 +776,7 @@ static snd_pcm_uframes_t snd_sonicvibes_capture_pointer(struct snd_pcm_substream
return bytes_to_frames(substream->runtime, ptr);
}
-static struct snd_pcm_hardware snd_sonicvibes_playback =
+static const struct snd_pcm_hardware snd_sonicvibes_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -795,7 +795,7 @@ static struct snd_pcm_hardware snd_sonicvibes_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_sonicvibes_capture =
+static const struct snd_pcm_hardware snd_sonicvibes_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 64d3b8eba4bb..eabd84d9ffee 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -1727,7 +1727,7 @@ static snd_pcm_uframes_t snd_trident_spdif_pointer(struct snd_pcm_substream *sub
* Playback support device description
*/
-static struct snd_pcm_hardware snd_trident_playback =
+static const struct snd_pcm_hardware snd_trident_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1752,7 +1752,7 @@ static struct snd_pcm_hardware snd_trident_playback =
* Capture support device description
*/
-static struct snd_pcm_hardware snd_trident_capture =
+static const struct snd_pcm_hardware snd_trident_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1777,7 +1777,7 @@ static struct snd_pcm_hardware snd_trident_capture =
* Foldback capture support device description
*/
-static struct snd_pcm_hardware snd_trident_foldback =
+static const struct snd_pcm_hardware snd_trident_foldback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1801,7 +1801,7 @@ static struct snd_pcm_hardware snd_trident_foldback =
* SPDIF playback support device description
*/
-static struct snd_pcm_hardware snd_trident_spdif =
+static const struct snd_pcm_hardware snd_trident_spdif =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1822,7 +1822,7 @@ static struct snd_pcm_hardware snd_trident_spdif =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_trident_spdif_7018 =
+static const struct snd_pcm_hardware snd_trident_spdif_7018 =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -2093,7 +2093,7 @@ static const struct snd_pcm_ops snd_trident_nx_playback_ops = {
.page = snd_pcm_sgbuf_ops_page,
};
-static struct snd_pcm_ops snd_trident_capture_ops = {
+static const struct snd_pcm_ops snd_trident_capture_ops = {
.open = snd_trident_capture_open,
.close = snd_trident_capture_close,
.ioctl = snd_trident_ioctl,
@@ -2104,7 +2104,7 @@ static struct snd_pcm_ops snd_trident_capture_ops = {
.pointer = snd_trident_capture_pointer,
};
-static struct snd_pcm_ops snd_trident_si7018_capture_ops = {
+static const struct snd_pcm_ops snd_trident_si7018_capture_ops = {
.open = snd_trident_capture_open,
.close = snd_trident_capture_close,
.ioctl = snd_trident_ioctl,
@@ -3363,11 +3363,9 @@ static int snd_trident_tlb_alloc(struct snd_trident *trident)
trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4);
/* allocate shadow TLB page table (virtual addresses) */
trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
- if (trident->tlb.shadow_entries == NULL) {
- dev_err(trident->card->dev,
- "unable to allocate shadow TLB entries\n");
+ if (!trident->tlb.shadow_entries)
return -ENOMEM;
- }
+
/* allocate and setup silent page and initialise TLB entries */
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci),
SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) {
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index c767b8664359..3a1c0b8b4ea2 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1150,7 +1150,7 @@ static int snd_via8233_capture_prepare(struct snd_pcm_substream *substream)
/*
* pcm hardware definition, identical for both playback and capture
*/
-static struct snd_pcm_hardware snd_via82xx_hw =
+static const struct snd_pcm_hardware snd_via82xx_hw =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 55f79b2599e7..8a69221c1b86 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -714,7 +714,7 @@ static int snd_via82xx_pcm_prepare(struct snd_pcm_substream *substream)
/*
* pcm hardware definition, identical for both playback and capture
*/
-static struct snd_pcm_hardware snd_via82xx_hw =
+static const struct snd_pcm_hardware snd_via82xx_hw =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 1114166c685c..edfd58248082 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -845,7 +845,7 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct snd_pcm_hardware snd_ymfpci_playback =
+static const struct snd_pcm_hardware snd_ymfpci_playback =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -867,7 +867,7 @@ static struct snd_pcm_hardware snd_ymfpci_playback =
.fifo_size = 0,
};
-static struct snd_pcm_hardware snd_ymfpci_capture =
+static const struct snd_pcm_hardware snd_ymfpci_capture =
{
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index b48aa0a78c19..4a2354b5ae00 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -193,7 +193,7 @@ static int pdacf_pcm_prepare(struct snd_pcm_substream *subs)
* capture hw information
*/
-static struct snd_pcm_hardware pdacf_pcm_capture_hw = {
+static const struct snd_pcm_hardware pdacf_pcm_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -266,7 +266,7 @@ static snd_pcm_uframes_t pdacf_pcm_capture_pointer(struct snd_pcm_substream *sub
/*
* operators for PCM capture
*/
-static struct snd_pcm_ops pdacf_pcm_capture_ops = {
+static const struct snd_pcm_ops pdacf_pcm_capture_ops = {
.open = pdacf_pcm_capture_open,
.close = pdacf_pcm_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index a5843fc5ff20..48dd44f8e914 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -509,7 +509,7 @@ static void snd_pmac_pcm_update(struct snd_pmac *chip, struct pmac_stream *rec)
* hw info
*/
-static struct snd_pcm_hardware snd_pmac_playback =
+static const struct snd_pcm_hardware snd_pmac_playback =
{
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
@@ -528,7 +528,7 @@ static struct snd_pcm_hardware snd_pmac_playback =
.periods_max = PMAC_MAX_FRAGS,
};
-static struct snd_pcm_hardware snd_pmac_capture =
+static const struct snd_pcm_hardware snd_pmac_capture =
{
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP |
@@ -681,7 +681,7 @@ static int snd_pmac_capture_close(struct snd_pcm_substream *subs)
/*
*/
-static struct snd_pcm_ops snd_pmac_playback_ops = {
+static const struct snd_pcm_ops snd_pmac_playback_ops = {
.open = snd_pmac_playback_open,
.close = snd_pmac_playback_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -692,7 +692,7 @@ static struct snd_pcm_ops snd_pmac_playback_ops = {
.pointer = snd_pmac_playback_pointer,
};
-static struct snd_pcm_ops snd_pmac_capture_ops = {
+static const struct snd_pcm_ops snd_pmac_capture_ops = {
.open = snd_pmac_capture_open,
.close = snd_pmac_capture_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index cdd44abfc9e0..36f34f434ecb 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -772,7 +772,7 @@ static struct snd_kcontrol_new spdif_ctls[] = {
},
};
-static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = {
+static const struct snd_pcm_ops snd_ps3_pcm_spdif_ops = {
.open = snd_ps3_pcm_open,
.close = snd_ps3_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index ab4802df62e1..fdc680ae8aa0 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -211,7 +211,7 @@ static void aica_chn_halt(void)
}
/* ALSA code below */
-static struct snd_pcm_hardware snd_pcm_aica_playback_hw = {
+static const struct snd_pcm_hardware snd_pcm_aica_playback_hw = {
.info = (SNDRV_PCM_INFO_NONINTERLEAVED),
.formats =
(SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |
@@ -436,7 +436,7 @@ static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream
return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER);
}
-static struct snd_pcm_ops snd_aicapcm_playback_ops = {
+static const struct snd_pcm_ops snd_aicapcm_playback_ops = {
.open = snd_aicapcm_pcm_open,
.close = snd_aicapcm_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index c1e00ed715ee..834b2574786f 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -93,7 +93,7 @@ static void dac_audio_set_rate(struct snd_sh_dac *chip)
/* PCM INTERFACE */
-static struct snd_pcm_hardware snd_sh_dac_pcm_hw = {
+static const struct snd_pcm_hardware snd_sh_dac_pcm_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED |
@@ -252,7 +252,7 @@ snd_pcm_uframes_t snd_sh_dac_pcm_pointer(struct snd_pcm_substream *substream)
}
/* pcm ops */
-static struct snd_pcm_ops snd_sh_dac_pcm_ops = {
+static const struct snd_pcm_ops snd_sh_dac_pcm_ops = {
.open = snd_sh_dac_pcm_open,
.close = snd_sh_dac_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
@@ -424,7 +424,7 @@ static int snd_sh_dac_probe(struct platform_device *devptr)
if (err < 0)
goto probe_error;
- snd_printk("ALSA driver for SuperH DAC audio");
+ snd_printk(KERN_INFO "ALSA driver for SuperH DAC audio");
platform_set_drvdata(devptr, card);
return 0;
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
index b7ef8c59b49a..0cd7caaed9c4 100644
--- a/sound/soc/atmel/atmel-classd.c
+++ b/sound/soc/atmel/atmel-classd.c
@@ -652,7 +652,6 @@ static int atmel_classd_probe(struct platform_device *pdev)
}
snd_soc_card_set_drvdata(card, dd);
- platform_set_drvdata(pdev, card);
ret = atmel_classd_asoc_card_init(dev, card);
if (ret) {
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c
index c917df7715d1..8e3d34be9e69 100644
--- a/sound/soc/atmel/atmel-pdmic.c
+++ b/sound/soc/atmel/atmel-pdmic.c
@@ -694,7 +694,6 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
}
snd_soc_card_set_drvdata(card, dd);
- platform_set_drvdata(pdev, card);
ret = atmel_pdmic_asoc_card_init(dev, card);
if (ret) {
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 5c73061d912a..301e1fc9a377 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -99,7 +99,7 @@ static int db1200_i2s_startup(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_soc_ops db1200_i2s_wm8731_ops = {
+static const struct snd_soc_ops db1200_i2s_wm8731_ops = {
.startup = db1200_i2s_startup,
};
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index b5d1caa04d8e..6a035ca0f521 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -304,7 +304,7 @@ static int au1xpsc_pcm_close(struct snd_pcm_substream *substream)
return 0;
}
-static struct snd_pcm_ops au1xpsc_pcm_ops = {
+static const struct snd_pcm_ops au1xpsc_pcm_ops = {
.open = au1xpsc_pcm_open,
.close = au1xpsc_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c
index fcf5a9adde81..19457e2b351e 100644
--- a/sound/soc/au1x/dma.c
+++ b/sound/soc/au1x/dma.c
@@ -277,7 +277,7 @@ static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss)
return bytes_to_frames(ss->runtime, location);
}
-static struct snd_pcm_ops alchemy_pcm_ops = {
+static const struct snd_pcm_ops alchemy_pcm_ops = {
.open = alchemy_pcm_open,
.close = alchemy_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index bb53c7059005..a2050ae5a3fe 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -474,7 +474,7 @@ static int au1xpsc_ac97_drvresume(struct device *dev)
return 0;
}
-static struct dev_pm_ops au1xpscac97_pmops = {
+static const struct dev_pm_ops au1xpscac97_pmops = {
.suspend = au1xpsc_ac97_drvsuspend,
.resume = au1xpsc_ac97_drvresume,
};
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 0bf9d62b91a0..e6eec081eaae 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -392,7 +392,7 @@ static int au1xpsc_i2s_drvresume(struct device *dev)
return 0;
}
-static struct dev_pm_ops au1xpsci2s_pmops = {
+static const struct dev_pm_ops au1xpsci2s_pmops = {
.suspend = au1xpsc_i2s_drvsuspend,
.resume = au1xpsc_i2s_drvresume,
};
diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c
index e710bb0c5637..15c438f0f22d 100644
--- a/sound/soc/bcm/cygnus-ssp.c
+++ b/sound/soc/bcm/cygnus-ssp.c
@@ -27,12 +27,6 @@
#define DEFAULT_VCO 1354750204
-#define CYGNUS_TDM_RATE \
- (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
- SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
- SNDRV_PCM_RATE_48000)
-
#define CAPTURE_FCI_ID_BASE 0x180
#define CYGNUS_SSP_TRISTATE_MASK 0x001fff
#define CYGNUS_PLLCLKSEL_MASK 0xf
@@ -234,152 +228,20 @@ static const struct pll_macro_entry pll_predef_mclk[] = {
{98304000, 2},
};
+#define CYGNUS_RATE_MIN 8000
+#define CYGNUS_RATE_MAX 384000
+
/* List of valid frame sizes for tdm mode */
static const int ssp_valid_tdm_framesize[] = {32, 64, 128, 256, 512};
-/*
- * Use this relationship to derive the sampling rate (lrclk)
- * lrclk = (mclk) / ((2*mclk_to_sclk_ratio) * (32 * SCLK))).
- *
- * Use mclk and pll_ch from the table above
- *
- * Valid SCLK = 0/1/2/4/8/12
- *
- * mclk_to_sclk_ratio = number of MCLK per SCLK. Division is twice the
- * value programmed in this field.
- * Valid mclk_to_sclk_ratio = 1 through to 15
- *
- * eg: To set lrclk = 48khz, set mclk = 12288000, mclk_to_sclk_ratio = 2,
- * SCLK = 64
- */
-struct _ssp_clk_coeff {
- u32 mclk;
- u32 sclk_rate;
- u32 rate;
- u32 mclk_rate;
+static const unsigned int cygnus_rates[] = {
+ 8000, 11025, 16000, 22050, 32000, 44100, 48000,
+ 88200, 96000, 176400, 192000, 352800, 384000
};
-static const struct _ssp_clk_coeff ssp_clk_coeff[] = {
- { 4096000, 32, 16000, 4},
- { 4096000, 32, 32000, 2},
- { 4096000, 64, 8000, 4},
- { 4096000, 64, 16000, 2},
- { 4096000, 64, 32000, 1},
- { 4096000, 128, 8000, 2},
- { 4096000, 128, 16000, 1},
- { 4096000, 256, 8000, 1},
-
- { 6144000, 32, 16000, 6},
- { 6144000, 32, 32000, 3},
- { 6144000, 32, 48000, 2},
- { 6144000, 32, 96000, 1},
- { 6144000, 64, 8000, 6},
- { 6144000, 64, 16000, 3},
- { 6144000, 64, 48000, 1},
- { 6144000, 128, 8000, 3},
-
- { 8192000, 32, 32000, 4},
- { 8192000, 64, 16000, 4},
- { 8192000, 64, 32000, 2},
- { 8192000, 128, 8000, 4},
- { 8192000, 128, 16000, 2},
- { 8192000, 128, 32000, 1},
- { 8192000, 256, 8000, 2},
- { 8192000, 256, 16000, 1},
- { 8192000, 512, 8000, 1},
-
- {12288000, 32, 32000, 6},
- {12288000, 32, 48000, 4},
- {12288000, 32, 96000, 2},
- {12288000, 32, 192000, 1},
- {12288000, 64, 16000, 6},
- {12288000, 64, 32000, 3},
- {12288000, 64, 48000, 2},
- {12288000, 64, 96000, 1},
- {12288000, 128, 8000, 6},
- {12288000, 128, 16000, 3},
- {12288000, 128, 48000, 1},
- {12288000, 256, 8000, 3},
-
- {16384000, 64, 32000, 4},
- {16384000, 128, 16000, 4},
- {16384000, 128, 32000, 2},
- {16384000, 256, 8000, 4},
- {16384000, 256, 16000, 2},
- {16384000, 256, 32000, 1},
- {16384000, 512, 8000, 2},
- {16384000, 512, 16000, 1},
-
- {24576000, 32, 96000, 4},
- {24576000, 32, 192000, 2},
- {24576000, 64, 32000, 6},
- {24576000, 64, 48000, 4},
- {24576000, 64, 96000, 2},
- {24576000, 64, 192000, 1},
- {24576000, 128, 16000, 6},
- {24576000, 128, 32000, 3},
- {24576000, 128, 48000, 2},
- {24576000, 256, 8000, 6},
- {24576000, 256, 16000, 3},
- {24576000, 256, 48000, 1},
- {24576000, 512, 8000, 3},
-
- {49152000, 32, 192000, 4},
- {49152000, 64, 96000, 4},
- {49152000, 64, 192000, 2},
- {49152000, 128, 32000, 6},
- {49152000, 128, 48000, 4},
- {49152000, 128, 96000, 2},
- {49152000, 128, 192000, 1},
- {49152000, 256, 16000, 6},
- {49152000, 256, 32000, 3},
- {49152000, 256, 48000, 2},
- {49152000, 256, 96000, 1},
- {49152000, 512, 8000, 6},
- {49152000, 512, 16000, 3},
- {49152000, 512, 48000, 1},
-
- { 5644800, 32, 22050, 4},
- { 5644800, 32, 44100, 2},
- { 5644800, 32, 88200, 1},
- { 5644800, 64, 11025, 4},
- { 5644800, 64, 22050, 2},
- { 5644800, 64, 44100, 1},
-
- {11289600, 32, 44100, 4},
- {11289600, 32, 88200, 2},
- {11289600, 32, 176400, 1},
- {11289600, 64, 22050, 4},
- {11289600, 64, 44100, 2},
- {11289600, 64, 88200, 1},
- {11289600, 128, 11025, 4},
- {11289600, 128, 22050, 2},
- {11289600, 128, 44100, 1},
-
- {22579200, 32, 88200, 4},
- {22579200, 32, 176400, 2},
- {22579200, 64, 44100, 4},
- {22579200, 64, 88200, 2},
- {22579200, 64, 176400, 1},
- {22579200, 128, 22050, 4},
- {22579200, 128, 44100, 2},
- {22579200, 128, 88200, 1},
- {22579200, 256, 11025, 4},
- {22579200, 256, 22050, 2},
- {22579200, 256, 44100, 1},
-
- {45158400, 32, 176400, 4},
- {45158400, 64, 88200, 4},
- {45158400, 64, 176400, 2},
- {45158400, 128, 44100, 4},
- {45158400, 128, 88200, 2},
- {45158400, 128, 176400, 1},
- {45158400, 256, 22050, 4},
- {45158400, 256, 44100, 2},
- {45158400, 256, 88200, 1},
- {45158400, 512, 11025, 4},
- {45158400, 512, 22050, 2},
- {45158400, 512, 44100, 1},
+static const struct snd_pcm_hw_constraint_list cygnus_rate_constraint = {
+ .count = ARRAY_SIZE(cygnus_rates),
+ .list = cygnus_rates,
};
static struct cygnus_aio_port *cygnus_dai_get_portinfo(struct snd_soc_dai *dai)
@@ -679,40 +541,55 @@ static int pll_configure_mclk(struct cygnus_audio *cygaud, u32 mclk,
return p_entry->pll_ch_num;
}
-static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio,
- struct cygnus_audio *cygaud)
+static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio)
{
- u32 value, i = 0;
+ u32 value;
u32 mask = 0xf;
u32 sclk;
- bool found = false;
- const struct _ssp_clk_coeff *p_entry = NULL;
+ u32 mclk_rate;
+ unsigned int bit_rate;
+ unsigned int ratio;
- for (i = 0; i < ARRAY_SIZE(ssp_clk_coeff); i++) {
- p_entry = &ssp_clk_coeff[i];
- if ((p_entry->rate == aio->lrclk) &&
- (p_entry->sclk_rate == aio->bit_per_frame) &&
- (p_entry->mclk == aio->mclk)) {
- found = true;
- break;
- }
- }
- if (!found) {
+ bit_rate = aio->bit_per_frame * aio->lrclk;
+
+ /*
+ * Check if the bit clock can be generated from the given MCLK.
+ * MCLK must be a perfect multiple of bit clock and must be one of the
+ * following values... (2,4,6,8,10,12,14)
+ */
+ if ((aio->mclk % bit_rate) != 0)
+ return -EINVAL;
+
+ ratio = aio->mclk / bit_rate;
+ switch (ratio) {
+ case 2:
+ case 4:
+ case 6:
+ case 8:
+ case 10:
+ case 12:
+ case 14:
+ mclk_rate = ratio / 2;
+ break;
+
+ default:
dev_err(aio->cygaud->dev,
- "No valid match found in ssp_clk_coeff array\n");
+ "Invalid combination of MCLK and BCLK\n");
dev_err(aio->cygaud->dev, "lrclk = %u, bits/frame = %u, mclk = %u\n",
aio->lrclk, aio->bit_per_frame, aio->mclk);
return -EINVAL;
}
- sclk = aio->bit_per_frame;
- if (sclk == 512)
- sclk = 0;
- /* sclks_per_1fs_div = sclk cycles/32 */
- sclk /= 32;
/* Set sclk rate */
switch (aio->port_type) {
case PORT_TDM:
+ sclk = aio->bit_per_frame;
+ if (sclk == 512)
+ sclk = 0;
+
+ /* sclks_per_1fs_div = sclk cycles/32 */
+ sclk /= 32;
+
/* Set number of bitclks per frame */
value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
value &= ~(mask << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32);
@@ -731,7 +608,7 @@ static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio,
/* Set MCLK_RATE ssp port (spdif and ssp are the same) */
value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
value &= ~(0xf << I2S_OUT_MCLKRATE_SHIFT);
- value |= (p_entry->mclk_rate << I2S_OUT_MCLKRATE_SHIFT);
+ value |= (mclk_rate << I2S_OUT_MCLKRATE_SHIFT);
writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
dev_dbg(aio->cygaud->dev, "mclk cfg reg = 0x%x\n", value);
@@ -745,7 +622,6 @@ static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
- struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
int rate, bitres;
u32 value;
u32 mask = 0x1f;
@@ -841,7 +717,7 @@ static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream,
aio->lrclk = rate;
if (!aio->is_slave)
- ret = cygnus_ssp_set_clocks(aio, cygaud);
+ ret = cygnus_ssp_set_clocks(aio);
return ret;
}
@@ -888,6 +764,11 @@ static int cygnus_ssp_startup(struct snd_pcm_substream *substream,
else
aio->clk_trace.cap_en = true;
+ substream->runtime->hw.rate_min = CYGNUS_RATE_MIN;
+ substream->runtime->hw.rate_max = CYGNUS_RATE_MAX;
+
+ snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE, &cygnus_rate_constraint);
return 0;
}
@@ -1261,9 +1142,7 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = {
.playback = { \
.channels_min = 1, \
.channels_max = 16, \
- .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
- SNDRV_PCM_RATE_192000, \
+ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S32_LE, \
@@ -1271,9 +1150,7 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = {
.capture = { \
.channels_min = 2, \
.channels_max = 16, \
- .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
- SNDRV_PCM_RATE_192000, \
+ .rates = SNDRV_PCM_RATE_KNOT, \
.formats = SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S32_LE, \
}, \
@@ -1288,14 +1165,12 @@ static const struct snd_soc_dai_driver cygnus_ssp_dai_info[] = {
INIT_CPU_DAI(2),
};
-static struct snd_soc_dai_driver cygnus_spdif_dai_info = {
+static const struct snd_soc_dai_driver cygnus_spdif_dai_info = {
.name = "cygnus-spdif",
.playback = {
.channels_min = 2,
.channels_max = 2,
- .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
+ .rates = SNDRV_PCM_RATE_KNOT,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S32_LE,
},
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 913e29275f4e..8c1d1983b8f9 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -308,7 +308,7 @@ static int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream,
}
#endif
-static struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
+static const struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
.open = bf5xx_pcm_open,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = bf5xx_pcm_hw_params,
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 470d99abf6f6..51cae76f14e6 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -318,7 +318,7 @@ static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
+static const struct snd_pcm_ops bf5xx_pcm_i2s_ops = {
.open = bf5xx_pcm_open,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = bf5xx_pcm_hw_params,
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c
index bd3b4d464145..819cff149a25 100644
--- a/sound/soc/blackfin/bf6xx-i2s.c
+++ b/sound/soc/blackfin/bf6xx-i2s.c
@@ -164,7 +164,7 @@ static int bfin_i2s_resume(struct snd_soc_dai *dai)
#define BFIN_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops bfin_i2s_dai_ops = {
+static const struct snd_soc_dai_ops bfin_i2s_dai_ops = {
.hw_params = bfin_i2s_hw_params,
.set_fmt = bfin_i2s_set_dai_fmt,
};
diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c
index dfb744381c42..d2caadfe7b6d 100644
--- a/sound/soc/blackfin/bf6xx-sport.c
+++ b/sound/soc/blackfin/bf6xx-sport.c
@@ -129,7 +129,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
for (i = 0; i < fragcount; ++i) {
desc[i].next_desc_addr = &(desc[i + 1]);
- desc[i].start_addr = (unsigned long)buf + i*fragsize;
+ desc[i].start_addr = (unsigned long)buf + i * fragsize;
desc[i].cfg = cfg;
desc[i].x_count = count;
desc[i].x_modify = wdsize;
@@ -138,7 +138,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
}
/* make circular */
- desc[fragcount-1].next_desc_addr = desc;
+ desc[fragcount - 1].next_desc_addr = desc;
}
int sport_config_tx_dma(struct sport_device *sport, void *buf,
@@ -148,7 +148,7 @@ int sport_config_tx_dma(struct sport_device *sport, void *buf,
unsigned int cfg;
dma_addr_t addr;
- count = fragsize/sport->wdsize;
+ count = fragsize / sport->wdsize;
if (sport->tx_desc)
dma_free_coherent(NULL, sport->tx_desc_size,
@@ -166,8 +166,7 @@ int sport_config_tx_dma(struct sport_device *sport, void *buf,
cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6;
setup_desc(sport->tx_desc, buf, fragcount, fragsize,
- cfg|DMAEN, count, sport->wdsize);
-
+ cfg | DMAEN, count, sport->wdsize);
return 0;
}
EXPORT_SYMBOL(sport_config_tx_dma);
@@ -179,7 +178,7 @@ int sport_config_rx_dma(struct sport_device *sport, void *buf,
unsigned int cfg;
dma_addr_t addr;
- count = fragsize/sport->wdsize;
+ count = fragsize / sport->wdsize;
if (sport->rx_desc)
dma_free_coherent(NULL, sport->rx_desc_size,
@@ -198,8 +197,7 @@ int sport_config_rx_dma(struct sport_device *sport, void *buf,
| WNR | NDSIZE_6;
setup_desc(sport->rx_desc, buf, fragcount, fragsize,
- cfg|DMAEN, count, sport->wdsize);
-
+ cfg | DMAEN, count, sport->wdsize);
return 0;
}
EXPORT_SYMBOL(sport_config_rx_dma);
@@ -226,7 +224,7 @@ static irqreturn_t sport_tx_irq(int irq, void *dev_id)
static unsigned long status;
status = get_dma_curr_irqstat(sport->tx_dma_chan);
- if (status & (DMA_DONE|DMA_ERR)) {
+ if (status & (DMA_DONE | DMA_ERR)) {
clear_dma_irqstat(sport->tx_dma_chan);
SSYNC();
}
@@ -241,7 +239,7 @@ static irqreturn_t sport_rx_irq(int irq, void *dev_id)
unsigned long status;
status = get_dma_curr_irqstat(sport->rx_dma_chan);
- if (status & (DMA_DONE|DMA_ERR)) {
+ if (status & (DMA_DONE | DMA_ERR)) {
clear_dma_irqstat(sport->rx_dma_chan);
SSYNC();
}
@@ -388,26 +386,24 @@ struct sport_device *sport_create(struct platform_device *pdev)
int ret;
sport = kzalloc(sizeof(*sport), GFP_KERNEL);
- if (!sport) {
- dev_err(dev, "Unable to allocate memory for sport device\n");
+ if (!sport)
return NULL;
- }
+
sport->pdev = pdev;
ret = sport_get_resource(sport);
- if (ret) {
- kfree(sport);
- return NULL;
- }
+ if (ret)
+ goto free_data;
ret = sport_request_resource(sport);
- if (ret) {
- kfree(sport);
- return NULL;
- }
+ if (ret)
+ goto free_data;
dev_dbg(dev, "SPORT create success\n");
return sport;
+free_data:
+ kfree(sport);
+ return NULL;
}
EXPORT_SYMBOL(sport_create);
diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c
index 85962657aabe..c53bd6f2c2d7 100644
--- a/sound/soc/cirrus/edb93xx.c
+++ b/sound/soc/cirrus/edb93xx.c
@@ -56,7 +56,7 @@ static int edb93xx_hw_params(struct snd_pcm_substream *substream,
SND_SOC_CLOCK_OUT);
}
-static struct snd_soc_ops edb93xx_ops = {
+static const struct snd_soc_ops edb93xx_ops = {
.hw_params = edb93xx_hw_params,
};
diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c
index 98089df08df6..2334ec19e7eb 100644
--- a/sound/soc/cirrus/snappercl15.c
+++ b/sound/soc/cirrus/snappercl15.c
@@ -45,7 +45,7 @@ static int snappercl15_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_soc_ops snappercl15_ops = {
+static const struct snd_soc_ops snappercl15_ops = {
.hw_params = snappercl15_hw_params,
};
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index b013a4c62b63..848c5fe49bc7 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1355,7 +1355,7 @@ static struct regmap *pm860x_get_regmap(struct device *dev)
return pm860x->regmap;
}
-static struct snd_soc_codec_driver soc_codec_dev_pm860x = {
+static const struct snd_soc_codec_driver soc_codec_dev_pm860x = {
.probe = pm860x_probe,
.remove = pm860x_remove,
.set_bias_level = pm860x_set_bias_level,
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6c78b0b49b81..c367d11079bc 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -60,6 +60,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS4271_I2C if I2C
select SND_SOC_CS4271_SPI if SPI_MASTER
select SND_SOC_CS42XX8_I2C if I2C
+ select SND_SOC_CS43130 if I2C
select SND_SOC_CS4349 if I2C
select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_CS53L30 if I2C
@@ -71,7 +72,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_DA732X if I2C
select SND_SOC_DA9055 if I2C
select SND_SOC_DIO2125
- select SND_SOC_DMIC
+ select SND_SOC_DMIC if GPIOLIB
select SND_SOC_ES8316 if I2C
select SND_SOC_ES8328_SPI if SPI_MASTER
select SND_SOC_ES8328_I2C if I2C
@@ -114,6 +115,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_PCM5102A
select SND_SOC_PCM512x_I2C if I2C
select SND_SOC_PCM512x_SPI if SPI_MASTER
+ select SND_SOC_RT274 if I2C
select SND_SOC_RT286 if I2C
select SND_SOC_RT298 if I2C
select SND_SOC_RT5514 if I2C
@@ -173,6 +175,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8400 if MFD_WM8400
select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8523 if I2C
+ select SND_SOC_WM8524 if GPIOLIB
select SND_SOC_WM8580 if I2C
select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8727
@@ -486,6 +489,11 @@ config SND_SOC_CS42XX8_I2C
select SND_SOC_CS42XX8
select REGMAP_I2C
+# Cirrus Logic CS43130 HiFi DAC
+config SND_SOC_CS43130
+ tristate "Cirrus Logic CS43130 CODEC"
+ depends on I2C
+
# Cirrus Logic CS4349 HiFi DAC
config SND_SOC_CS4349
tristate "Cirrus Logic CS4349 CODEC"
@@ -716,11 +724,17 @@ config SND_SOC_RL6231
config SND_SOC_RL6347A
tristate
+ default y if SND_SOC_RT274=y
default y if SND_SOC_RT286=y
default y if SND_SOC_RT298=y
+ default m if SND_SOC_RT274=m
default m if SND_SOC_RT286=m
default m if SND_SOC_RT298=m
+config SND_SOC_RT274
+ tristate
+ depends on I2C
+
config SND_SOC_RT286
tristate
depends on I2C
@@ -967,6 +981,10 @@ config SND_SOC_WM8523
tristate "Wolfson Microelectronics WM8523 DAC"
depends on I2C
+config SND_SOC_WM8524
+ tristate "Wolfson Microelectronics WM8524 DAC"
+ depends on GPIOLIB
+
config SND_SOC_WM8580
tristate "Wolfson Microelectronics WM8580 and WM8581 CODECs"
depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 1755a54e3dc9..77c18189c9ad 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -53,6 +53,7 @@ snd-soc-cs4271-i2c-objs := cs4271-i2c.o
snd-soc-cs4271-spi-objs := cs4271-spi.o
snd-soc-cs42xx8-objs := cs42xx8.o
snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
+snd-soc-cs43130-objs := cs43130.o
snd-soc-cs4349-objs := cs4349.o
snd-soc-cs47l24-objs := cs47l24.o
snd-soc-cs53l30-objs := cs53l30.o
@@ -113,6 +114,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
snd-soc-rl6231-objs := rl6231.o
snd-soc-rl6347a-objs := rl6347a.o
+snd-soc-rt274-objs := rt274.o
snd-soc-rt286-objs := rt286.o
snd-soc-rt298-objs := rt298.o
snd-soc-rt5514-objs := rt5514.o
@@ -182,6 +184,7 @@ snd-soc-wm8350-objs := wm8350.o
snd-soc-wm8400-objs := wm8400.o
snd-soc-wm8510-objs := wm8510.o
snd-soc-wm8523-objs := wm8523.o
+snd-soc-wm8524-objs := wm8524.o
snd-soc-wm8580-objs := wm8580.o
snd-soc-wm8711-objs := wm8711.o
snd-soc-wm8727-objs := wm8727.o
@@ -290,6 +293,7 @@ obj-$(CONFIG_SND_SOC_CS4271_I2C) += snd-soc-cs4271-i2c.o
obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o
obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
+obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o
obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o
@@ -320,6 +324,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o
obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
+obj-$(CONFIG_SND_SOC_MAX98371) += snd-soc-max98371.o
obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
@@ -349,6 +354,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
+obj-$(CONFIG_SND_SOC_RT274) += snd-soc-rt274.o
obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o
@@ -372,6 +378,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
+obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o
obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o
@@ -414,6 +421,7 @@ obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
+obj-$(CONFIG_SND_SOC_WM8524) += snd-soc-wm8524.o
obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 312b2a11abb6..006627b8c3a8 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -2523,7 +2523,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
return status;
}
-static struct snd_soc_codec_driver ab8500_codec_driver = {
+static const struct snd_soc_codec_driver ab8500_codec_driver = {
.probe = ab8500_codec_probe,
.component_driver = {
.controls = ab8500_ctrls,
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index f7f04c6be01e..440b4ce54376 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -112,7 +112,7 @@ static int ac97_soc_resume(struct snd_soc_codec *codec)
#define ac97_soc_resume NULL
#endif
-static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ac97 = {
.probe = ac97_soc_probe,
.suspend = ac97_soc_suspend,
.resume = ac97_soc_resume,
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index a478239aadac..d0361caad09e 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -321,7 +321,7 @@ static int ad1836_remove(struct snd_soc_codec *codec)
AD1836_ADC_SERFMT_MASK, 0);
}
-static struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ad1836 = {
.probe = ad1836_probe,
.remove = ad1836_remove,
.suspend = ad1836_suspend,
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index d643557d89a7..d10988eec0c1 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -408,7 +408,7 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
+static const struct snd_soc_codec_driver soc_codec_dev_ad193x = {
.probe = ad193x_codec_probe,
.component_driver = {
.controls = ad193x_snd_controls,
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index b7c1b9f4bf5f..ce89bfb42094 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -295,7 +295,7 @@ static int ad1980_soc_remove(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
.probe = ad1980_soc_probe,
.remove = ad1980_soc_remove,
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index 3e358a49442d..d8d86a0fea60 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -54,7 +54,7 @@ static struct snd_soc_dai_driver ad73311_dai = {
.formats = SNDRV_PCM_FMTBIT_S16_LE, },
};
-static struct snd_soc_codec_driver soc_codec_dev_ad73311 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ad73311 = {
.component_driver = {
.dapm_widgets = ad73311_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets),
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 8fa9045571ff..a865945d776a 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1458,7 +1458,7 @@ static const struct regmap_config adau1373_regmap_config = {
.num_reg_defaults = ARRAY_SIZE(adau1373_reg_defaults),
};
-static struct snd_soc_codec_driver adau1373_codec_driver = {
+static const struct snd_soc_codec_driver adau1373_codec_driver = {
.probe = adau1373_probe,
.resume = adau1373_resume,
.set_bias_level = adau1373_set_bias_level,
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 3bad1bc8c00a..805afac8146b 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -757,7 +757,7 @@ static int adau1701_resume(struct snd_soc_codec *codec)
#define adau1701_suspend NULL
#endif /* CONFIG_PM */
-static struct snd_soc_codec_driver adau1701_codec_drv = {
+static const struct snd_soc_codec_driver adau1701_codec_drv = {
.probe = adau1701_probe,
.remove = adau1701_remove,
.resume = adau1701_resume,
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c
index b319db6a69f8..e384f212beb2 100644
--- a/sound/soc/codecs/adau1977.c
+++ b/sound/soc/codecs/adau1977.c
@@ -388,8 +388,7 @@ static int adau1977_power_disable(struct adau1977 *adau1977)
regcache_mark_dirty(adau1977->regmap);
- if (adau1977->reset_gpio)
- gpiod_set_value_cansleep(adau1977->reset_gpio, 0);
+ gpiod_set_value_cansleep(adau1977->reset_gpio, 0);
regcache_cache_only(adau1977->regmap, true);
@@ -420,8 +419,7 @@ static int adau1977_power_enable(struct adau1977 *adau1977)
goto err_disable_avdd;
}
- if (adau1977->reset_gpio)
- gpiod_set_value_cansleep(adau1977->reset_gpio, 1);
+ gpiod_set_value_cansleep(adau1977->reset_gpio, 1);
regcache_cache_only(adau1977->regmap, false);
@@ -867,7 +865,7 @@ static int adau1977_codec_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver adau1977_codec_driver = {
+static const struct snd_soc_codec_driver adau1977_codec_driver = {
.probe = adau1977_codec_probe,
.set_bias_level = adau1977_set_bias_level,
.set_sysclk = adau1977_set_sysclk,
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index 6e793ebb5883..da7ca81f47cf 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -825,7 +825,7 @@ static int adav80x_resume(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver adav80x_codec_driver = {
+static const struct snd_soc_codec_driver adav80x_codec_driver = {
.probe = adav80x_probe,
.resume = adav80x_resume,
.set_bias_level = adav80x_set_bias_level,
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index 90c756d183b4..b7f0057c0239 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -58,7 +58,7 @@ static struct snd_soc_dai_driver ads117x_dai = {
.formats = ADS117X_FORMATS,},
};
-static struct snd_soc_codec_driver soc_codec_dev_ads117x = {
+static const struct snd_soc_codec_driver soc_codec_dev_ads117x = {
.component_driver = {
.dapm_widgets = ads117x_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets),
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 1a9d233c94d0..dbb184118f2e 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -242,7 +242,7 @@ static int ak4104_soc_resume(struct snd_soc_codec *codec)
#define ak4104_soc_resume NULL
#endif /* CONFIG_PM */
-static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
+static const struct snd_soc_codec_driver soc_codec_device_ak4104 = {
.probe = ak4104_probe,
.remove = ak4104_remove,
.suspend = ak4104_soc_suspend,
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 66cfffde9a12..e3c157dc88db 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -390,7 +390,7 @@ static const struct regmap_config ak4535_regmap = {
.num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
};
-static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
.resume = ak4535_resume,
.set_bias_level = ak4535_set_bias_level,
.suspend_bias_off = true,
diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c
index b92c548b9d29..0bb4fe5c122a 100644
--- a/sound/soc/codecs/ak4554.c
+++ b/sound/soc/codecs/ak4554.c
@@ -64,7 +64,7 @@ static struct snd_soc_dai_driver ak4554_dai = {
.symmetric_rates = 1,
};
-static struct snd_soc_codec_driver soc_codec_dev_ak4554 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ak4554 = {
.component_driver = {
.dapm_widgets = ak4554_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets),
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index 690edebf029e..b95bb8b52e51 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -522,7 +522,7 @@ static int ak4613_resume(struct snd_soc_codec *codec)
return regcache_sync(regmap);
}
-static struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
.suspend = ak4613_suspend,
.resume = ak4613_resume,
.set_bias_level = ak4613_set_bias_level,
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index ebdaf56c1d61..60142ff32d4f 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -524,7 +524,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = {
},
};
-static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
.component_driver = {
.controls = ak4641_snd_controls,
.num_controls = ARRAY_SIZE(ak4641_snd_controls),
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 66de8a2013a6..29530c567bd9 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -550,7 +550,7 @@ static int ak4642_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
.probe = ak4642_probe,
.suspend = ak4642_suspend,
.resume = ak4642_resume,
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 6088afaabf62..dcfdff56fc5a 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -610,7 +610,7 @@ static struct snd_soc_dai_driver ak4671_dai = {
.ops = &ak4671_dai_ops,
};
-static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
.set_bias_level = ak4671_set_bias_level,
.component_driver = {
.controls = ak4671_snd_controls,
diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c
index 0ef2df223336..d0e16c03815c 100644
--- a/sound/soc/codecs/ak5386.c
+++ b/sound/soc/codecs/ak5386.c
@@ -69,7 +69,7 @@ static int ak5386_soc_resume(struct snd_soc_codec *codec)
#define ak5386_soc_resume NULL
#endif /* CONFIG_PM */
-static struct snd_soc_codec_driver soc_codec_ak5386 = {
+static const struct snd_soc_codec_driver soc_codec_ak5386 = {
.probe = ak5386_soc_probe,
.remove = ak5386_soc_remove,
.suspend = ak5386_soc_suspend,
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index d2e3a3ef7499..1db965a93632 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -951,7 +951,7 @@ static int alc5623_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
+static const struct snd_soc_codec_driver soc_codec_device_alc5623 = {
.probe = alc5623_probe,
.suspend = alc5623_suspend,
.resume = alc5623_resume,
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 0a734d910850..a1149f6a8450 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -710,7 +710,7 @@ const struct soc_enum arizona_anc_input_src[] = {
ARRAY_SIZE(arizona_anc_input_src_text),
arizona_anc_input_src_text),
SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL,
- ARIZONA_FCL_MIC_MODE_SEL,
+ ARIZONA_FCL_MIC_MODE_SEL_SHIFT,
ARRAY_SIZE(arizona_anc_channel_src_text),
arizona_anc_channel_src_text),
SOC_ENUM_SINGLE(ARIZONA_ANC_SRC,
@@ -718,7 +718,7 @@ const struct soc_enum arizona_anc_input_src[] = {
ARRAY_SIZE(arizona_anc_input_src_text),
arizona_anc_input_src_text),
SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL,
- ARIZONA_FCR_MIC_MODE_SEL,
+ ARIZONA_FCR_MIC_MODE_SEL_SHIFT,
ARRAY_SIZE(arizona_anc_channel_src_text),
arizona_anc_channel_src_text),
};
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index 8014e697d540..806191addb44 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -62,7 +62,7 @@ static struct snd_soc_dai_driver bt_sco_dai[] = {
}
};
-static struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
+static const struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
.component_driver = {
.dapm_widgets = bt_sco_widgets,
.num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets),
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 7a2d9a2ee427..6ed2cc374768 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -128,7 +128,7 @@ static struct regmap *cq93vc_get_regmap(struct device *dev)
return davinci_vc->regmap;
}
-static struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
+static const struct snd_soc_codec_driver soc_codec_dev_cq93vc = {
.set_bias_level = cq93vc_set_bias_level,
.get_regmap = cq93vc_get_regmap,
.component_driver = {
diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c
index 6df29fa30fb9..854cf8f27605 100644
--- a/sound/soc/codecs/cs35l33.c
+++ b/sound/soc/codecs/cs35l33.c
@@ -831,7 +831,7 @@ static int cs35l33_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = {
+static const struct snd_soc_codec_driver soc_codec_dev_cs35l33 = {
.probe = cs35l33_probe,
.set_bias_level = cs35l33_set_bias_level,
@@ -869,8 +869,7 @@ static int __maybe_unused cs35l33_runtime_resume(struct device *dev)
dev_dbg(dev, "%s\n", __func__);
- if (cs35l33->reset_gpio)
- gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
+ gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
ret = regulator_bulk_enable(cs35l33->num_core_supplies,
cs35l33->core_supplies);
@@ -881,8 +880,7 @@ static int __maybe_unused cs35l33_runtime_resume(struct device *dev)
regcache_cache_only(cs35l33->regmap, false);
- if (cs35l33->reset_gpio)
- gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);
+ gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);
msleep(CS35L33_BOOT_DELAY);
@@ -1191,8 +1189,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client,
return ret;
}
- if (cs35l33->reset_gpio)
- gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);
+ gpiod_set_value_cansleep(cs35l33->reset_gpio, 1);
msleep(CS35L33_BOOT_DELAY);
regcache_cache_only(cs35l33->regmap, false);
@@ -1262,8 +1259,7 @@ static int cs35l33_i2c_remove(struct i2c_client *client)
snd_soc_unregister_codec(&client->dev);
- if (cs35l33->reset_gpio)
- gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
+ gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
pm_runtime_disable(&client->dev);
regulator_bulk_disable(cs35l33->num_core_supplies,
diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c
index 0a747c66cc6c..1e05026bedca 100644
--- a/sound/soc/codecs/cs35l34.c
+++ b/sound/soc/codecs/cs35l34.c
@@ -779,7 +779,7 @@ static int cs35l34_probe(struct snd_soc_codec *codec)
}
-static struct snd_soc_codec_driver soc_codec_dev_cs35l34 = {
+static const struct snd_soc_codec_driver soc_codec_dev_cs35l34 = {
.probe = cs35l34_probe,
.component_driver = {
@@ -1138,8 +1138,7 @@ static int cs35l34_i2c_remove(struct i2c_client *client)
snd_soc_unregister_codec(&client->dev);
- if (cs35l34->reset_gpio)
- gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);
+ gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);
pm_runtime_disable(&client->dev);
regulator_bulk_disable(cs35l34->num_core_supplies,
diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c
index f1ee184ecab2..129978d1243e 100644
--- a/sound/soc/codecs/cs35l35.c
+++ b/sound/soc/codecs/cs35l35.c
@@ -1079,7 +1079,7 @@ static int cs35l35_codec_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_cs35l35 = {
+static const struct snd_soc_codec_driver soc_codec_dev_cs35l35 = {
.probe = cs35l35_codec_probe,
.set_sysclk = cs35l35_codec_set_sysclk,
.component_driver = {
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index d8824773dc29..49a80627af12 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -639,7 +639,7 @@ static int cs4271_codec_remove(struct snd_soc_codec *codec)
return 0;
};
-static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
+static const struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
.probe = cs4271_codec_probe,
.remove = cs4271_codec_remove,
.suspend = cs4271_soc_suspend,
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index 55e4520cdcaf..a2324a0e72ee 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -911,7 +911,7 @@ static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute)
SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops cs42l42_ops = {
+static const struct snd_soc_dai_ops cs42l42_ops = {
.hw_params = cs42l42_pcm_hw_params,
.set_fmt = cs42l42_set_dai_fmt,
.set_sysclk = cs42l42_set_sysclk,
@@ -1898,8 +1898,7 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client)
snd_soc_unregister_codec(&i2c_client->dev);
/* Hold down reset */
- if (cs42l42->reset_gpio)
- gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
+ gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
return 0;
}
@@ -1913,8 +1912,7 @@ static int cs42l42_runtime_suspend(struct device *dev)
regcache_mark_dirty(cs42l42->regmap);
/* Hold down reset */
- if (cs42l42->reset_gpio)
- gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
+ gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
/* remove power */
regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies),
@@ -1937,8 +1935,7 @@ static int cs42l42_runtime_resume(struct device *dev)
return ret;
}
- if (cs42l42->reset_gpio)
- gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
+ gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
regcache_cache_only(cs42l42->regmap, false);
regcache_sync(cs42l42->regmap);
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 96cfe38943cd..f8072f1897d4 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -504,7 +504,7 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
+static const struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
.probe = cs42l51_codec_probe,
.component_driver = {
diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c
new file mode 100644
index 000000000000..643e37fc218e
--- /dev/null
+++ b/sound/soc/codecs/cs43130.c
@@ -0,0 +1,2694 @@
+/*
+ * cs43130.c -- CS43130 ALSA Soc Audio driver
+ *
+ * Copyright 2017 Cirrus Logic, Inc.
+ *
+ * Authors: Li Xu <li.xu@cirrus.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+#include <linux/of_irq.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <sound/jack.h>
+
+#include "cs43130.h"
+
+static const struct reg_default cs43130_reg_defaults[] = {
+ {CS43130_SYS_CLK_CTL_1, 0x06},
+ {CS43130_SP_SRATE, 0x01},
+ {CS43130_SP_BITSIZE, 0x05},
+ {CS43130_PAD_INT_CFG, 0x03},
+ {CS43130_PWDN_CTL, 0xFE},
+ {CS43130_CRYSTAL_SET, 0x04},
+ {CS43130_PLL_SET_1, 0x00},
+ {CS43130_PLL_SET_2, 0x00},
+ {CS43130_PLL_SET_3, 0x00},
+ {CS43130_PLL_SET_4, 0x00},
+ {CS43130_PLL_SET_5, 0x40},
+ {CS43130_PLL_SET_6, 0x10},
+ {CS43130_PLL_SET_7, 0x80},
+ {CS43130_PLL_SET_8, 0x03},
+ {CS43130_PLL_SET_9, 0x02},
+ {CS43130_PLL_SET_10, 0x02},
+ {CS43130_CLKOUT_CTL, 0x00},
+ {CS43130_ASP_NUM_1, 0x01},
+ {CS43130_ASP_NUM_2, 0x00},
+ {CS43130_ASP_DEN_1, 0x08},
+ {CS43130_ASP_DEN_2, 0x00},
+ {CS43130_ASP_LRCK_HI_TIME_1, 0x1F},
+ {CS43130_ASP_LRCK_HI_TIME_2, 0x00},
+ {CS43130_ASP_LRCK_PERIOD_1, 0x3F},
+ {CS43130_ASP_LRCK_PERIOD_2, 0x00},
+ {CS43130_ASP_CLOCK_CONF, 0x0C},
+ {CS43130_ASP_FRAME_CONF, 0x0A},
+ {CS43130_XSP_NUM_1, 0x01},
+ {CS43130_XSP_NUM_2, 0x00},
+ {CS43130_XSP_DEN_1, 0x02},
+ {CS43130_XSP_DEN_2, 0x00},
+ {CS43130_XSP_LRCK_HI_TIME_1, 0x1F},
+ {CS43130_XSP_LRCK_HI_TIME_2, 0x00},
+ {CS43130_XSP_LRCK_PERIOD_1, 0x3F},
+ {CS43130_XSP_LRCK_PERIOD_2, 0x00},
+ {CS43130_XSP_CLOCK_CONF, 0x0C},
+ {CS43130_XSP_FRAME_CONF, 0x0A},
+ {CS43130_ASP_CH_1_LOC, 0x00},
+ {CS43130_ASP_CH_2_LOC, 0x00},
+ {CS43130_ASP_CH_1_SZ_EN, 0x06},
+ {CS43130_ASP_CH_2_SZ_EN, 0x0E},
+ {CS43130_XSP_CH_1_LOC, 0x00},
+ {CS43130_XSP_CH_2_LOC, 0x00},
+ {CS43130_XSP_CH_1_SZ_EN, 0x06},
+ {CS43130_XSP_CH_2_SZ_EN, 0x0E},
+ {CS43130_DSD_VOL_B, 0x78},
+ {CS43130_DSD_VOL_A, 0x78},
+ {CS43130_DSD_PATH_CTL_1, 0xA8},
+ {CS43130_DSD_INT_CFG, 0x00},
+ {CS43130_DSD_PATH_CTL_2, 0x02},
+ {CS43130_DSD_PCM_MIX_CTL, 0x00},
+ {CS43130_DSD_PATH_CTL_3, 0x40},
+ {CS43130_HP_OUT_CTL_1, 0x30},
+ {CS43130_PCM_FILT_OPT, 0x02},
+ {CS43130_PCM_VOL_B, 0x78},
+ {CS43130_PCM_VOL_A, 0x78},
+ {CS43130_PCM_PATH_CTL_1, 0xA8},
+ {CS43130_PCM_PATH_CTL_2, 0x00},
+ {CS43130_CLASS_H_CTL, 0x1E},
+ {CS43130_HP_DETECT, 0x04},
+ {CS43130_HP_LOAD_1, 0x00},
+ {CS43130_HP_MEAS_LOAD_1, 0x00},
+ {CS43130_HP_MEAS_LOAD_2, 0x00},
+ {CS43130_INT_MASK_1, 0xFF},
+ {CS43130_INT_MASK_2, 0xFF},
+ {CS43130_INT_MASK_3, 0xFF},
+ {CS43130_INT_MASK_4, 0xFF},
+ {CS43130_INT_MASK_5, 0xFF},
+};
+
+static bool cs43130_volatile_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
+ case CS43130_HP_DC_STAT_1 ... CS43130_HP_DC_STAT_2:
+ case CS43130_HP_AC_STAT_1 ... CS43130_HP_AC_STAT_2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool cs43130_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS43130_DEVID_AB ... CS43130_SYS_CLK_CTL_1:
+ case CS43130_SP_SRATE ... CS43130_PAD_INT_CFG:
+ case CS43130_PWDN_CTL:
+ case CS43130_CRYSTAL_SET:
+ case CS43130_PLL_SET_1 ... CS43130_PLL_SET_5:
+ case CS43130_PLL_SET_6:
+ case CS43130_PLL_SET_7:
+ case CS43130_PLL_SET_8:
+ case CS43130_PLL_SET_9:
+ case CS43130_PLL_SET_10:
+ case CS43130_CLKOUT_CTL:
+ case CS43130_ASP_NUM_1 ... CS43130_ASP_FRAME_CONF:
+ case CS43130_XSP_NUM_1 ... CS43130_XSP_FRAME_CONF:
+ case CS43130_ASP_CH_1_LOC:
+ case CS43130_ASP_CH_2_LOC:
+ case CS43130_ASP_CH_1_SZ_EN:
+ case CS43130_ASP_CH_2_SZ_EN:
+ case CS43130_XSP_CH_1_LOC:
+ case CS43130_XSP_CH_2_LOC:
+ case CS43130_XSP_CH_1_SZ_EN:
+ case CS43130_XSP_CH_2_SZ_EN:
+ case CS43130_DSD_VOL_B ... CS43130_DSD_PATH_CTL_3:
+ case CS43130_HP_OUT_CTL_1:
+ case CS43130_PCM_FILT_OPT ... CS43130_PCM_PATH_CTL_2:
+ case CS43130_CLASS_H_CTL:
+ case CS43130_HP_DETECT:
+ case CS43130_HP_STATUS:
+ case CS43130_HP_LOAD_1:
+ case CS43130_HP_MEAS_LOAD_1:
+ case CS43130_HP_MEAS_LOAD_2:
+ case CS43130_HP_DC_STAT_1:
+ case CS43130_HP_DC_STAT_2:
+ case CS43130_HP_AC_STAT_1:
+ case CS43130_HP_AC_STAT_2:
+ case CS43130_HP_LOAD_STAT:
+ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
+ case CS43130_INT_MASK_1 ... CS43130_INT_MASK_5:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool cs43130_precious_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:
+ return true;
+ default:
+ return false;
+ }
+}
+
+struct cs43130_pll_params {
+ unsigned int pll_in;
+ u8 sclk_prediv;
+ u8 pll_div_int;
+ u32 pll_div_frac;
+ u8 pll_mode;
+ u8 pll_divout;
+ unsigned int pll_out;
+ u8 pll_cal_ratio;
+};
+
+static const struct cs43130_pll_params pll_ratio_table[] = {
+ {9600000, 0x02, 0x49, 0x800000, 0x00, 0x08, 22579200, 151},
+ {9600000, 0x02, 0x50, 0x000000, 0x00, 0x08, 24576000, 164},
+
+ {11289600, 0x02, 0X40, 0, 0x01, 0x08, 22579200, 128},
+ {11289600, 0x02, 0x44, 0x06F700, 0x0, 0x08, 24576000, 139},
+
+ {12000000, 0x02, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120},
+ {12000000, 0x02, 0x40, 0x000000, 0x00, 0x08, 24576000, 131},
+
+ {12288000, 0x02, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118},
+ {12288000, 0x02, 0x40, 0x000000, 0x01, 0x08, 24576000, 128},
+
+ {13000000, 0x02, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111},
+ {13000000, 0x02, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121},
+
+ {19200000, 0x03, 0x49, 0x800000, 0x00, 0x08, 22579200, 151},
+ {19200000, 0x03, 0x50, 0x000000, 0x00, 0x08, 24576000, 164},
+
+ {22579200, 0, 0, 0, 0, 0, 22579200, 0},
+ {22579200, 0x03, 0x44, 0x06F700, 0x00, 0x08, 24576000, 139},
+
+ {24000000, 0x03, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120},
+ {24000000, 0x03, 0x40, 0x000000, 0x00, 0x08, 24576000, 131},
+
+ {24576000, 0x03, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118},
+ {24576000, 0, 0, 0, 0, 0, 24576000, 0},
+
+ {26000000, 0x03, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111},
+ {26000000, 0x03, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121},
+};
+
+static const struct cs43130_pll_params *cs43130_get_pll_table(
+ unsigned int freq_in, unsigned int freq_out)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
+ if (pll_ratio_table[i].pll_in == freq_in &&
+ pll_ratio_table[i].pll_out == freq_out)
+ return &pll_ratio_table[i];
+ }
+
+ return NULL;
+}
+
+static int cs43130_pll_config(struct snd_soc_codec *codec)
+{
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+ const struct cs43130_pll_params *pll_entry;
+
+ dev_dbg(codec->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n",
+ cs43130->mclk, cs43130->mclk_int);
+
+ pll_entry = cs43130_get_pll_table(cs43130->mclk, cs43130->mclk_int);
+ if (!pll_entry)
+ return -EINVAL;
+
+ if (pll_entry->pll_cal_ratio == 0) {
+ regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1,
+ CS43130_PLL_START_MASK, 0);
+
+ cs43130->pll_bypass = true;
+ return 0;
+ }
+
+ cs43130->pll_bypass = false;
+
+ regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_2,
+ CS43130_PLL_DIV_DATA_MASK,
+ pll_entry->pll_div_frac >>
+ CS43130_PLL_DIV_FRAC_0_DATA_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_3,
+ CS43130_PLL_DIV_DATA_MASK,
+ pll_entry->pll_div_frac >>
+ CS43130_PLL_DIV_FRAC_1_DATA_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_4,
+ CS43130_PLL_DIV_DATA_MASK,
+ pll_entry->pll_div_frac >>
+ CS43130_PLL_DIV_FRAC_2_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_PLL_SET_5,
+ pll_entry->pll_div_int);
+ regmap_write(cs43130->regmap, CS43130_PLL_SET_6, pll_entry->pll_divout);
+ regmap_write(cs43130->regmap, CS43130_PLL_SET_7,
+ pll_entry->pll_cal_ratio);
+ regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_8,
+ CS43130_PLL_MODE_MASK,
+ pll_entry->pll_mode << CS43130_PLL_MODE_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_PLL_SET_9,
+ pll_entry->sclk_prediv);
+ regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1,
+ CS43130_PLL_START_MASK, 1);
+
+ return 0;
+}
+
+static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+ unsigned int freq_in, unsigned int freq_out)
+{
+ int ret = 0;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ switch (freq_in) {
+ case 9600000:
+ case 11289600:
+ case 12000000:
+ case 12288000:
+ case 13000000:
+ case 19200000:
+ case 22579200:
+ case 24000000:
+ case 24576000:
+ case 26000000:
+ cs43130->mclk = freq_in;
+ break;
+ default:
+ dev_err(codec->dev,
+ "unsupported pll input reference clock:%d\n", freq_in);
+ return -EINVAL;
+ }
+
+ switch (freq_out) {
+ case 22579200:
+ cs43130->mclk_int = freq_out;
+ break;
+ case 24576000:
+ cs43130->mclk_int = freq_out;
+ break;
+ default:
+ dev_err(codec->dev,
+ "unsupported pll output ref clock: %u\n", freq_out);
+ return -EINVAL;
+ }
+
+ ret = cs43130_pll_config(codec);
+ dev_dbg(codec->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass);
+ return ret;
+}
+
+static int cs43130_change_clksrc(struct snd_soc_codec *codec,
+ enum cs43130_mclk_src_sel src)
+{
+ int ret;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+ int mclk_int_decoded;
+
+ if (src == cs43130->mclk_int_src) {
+ /* clk source has not changed */
+ return 0;
+ }
+
+ switch (cs43130->mclk_int) {
+ case CS43130_MCLK_22M:
+ mclk_int_decoded = CS43130_MCLK_22P5;
+ break;
+ case CS43130_MCLK_24M:
+ mclk_int_decoded = CS43130_MCLK_24P5;
+ break;
+ default:
+ dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int);
+ return -EINVAL;
+ }
+
+ switch (src) {
+ case CS43130_MCLK_SRC_EXT:
+ cs43130->pll_bypass = true;
+ cs43130->mclk_int_src = CS43130_MCLK_SRC_EXT;
+ if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) {
+ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
+ CS43130_PDN_XTAL_MASK,
+ 1 << CS43130_PDN_XTAL_SHIFT);
+ } else {
+ reinit_completion(&cs43130->xtal_rdy);
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_XTAL_RDY_INT_MASK, 0);
+ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
+ CS43130_PDN_XTAL_MASK, 0);
+ ret = wait_for_completion_timeout(&cs43130->xtal_rdy,
+ msecs_to_jiffies(100));
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_XTAL_RDY_INT_MASK,
+ 1 << CS43130_XTAL_RDY_INT_SHIFT);
+ if (ret == 0) {
+ dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
+ CS43130_MCLK_SRC_SEL_MASK,
+ src << CS43130_MCLK_SRC_SEL_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
+ CS43130_MCLK_INT_MASK,
+ mclk_int_decoded << CS43130_MCLK_INT_SHIFT);
+ usleep_range(150, 200);
+
+ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
+ CS43130_PDN_PLL_MASK,
+ 1 << CS43130_PDN_PLL_SHIFT);
+ break;
+ case CS43130_MCLK_SRC_PLL:
+ cs43130->pll_bypass = false;
+ cs43130->mclk_int_src = CS43130_MCLK_SRC_PLL;
+ if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) {
+ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
+ CS43130_PDN_XTAL_MASK,
+ 1 << CS43130_PDN_XTAL_SHIFT);
+ } else {
+ reinit_completion(&cs43130->xtal_rdy);
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_XTAL_RDY_INT_MASK, 0);
+ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
+ CS43130_PDN_XTAL_MASK, 0);
+ ret = wait_for_completion_timeout(&cs43130->xtal_rdy,
+ msecs_to_jiffies(100));
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_XTAL_RDY_INT_MASK,
+ 1 << CS43130_XTAL_RDY_INT_SHIFT);
+ if (ret == 0) {
+ dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ reinit_completion(&cs43130->pll_rdy);
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_PLL_RDY_INT_MASK, 0);
+ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
+ CS43130_PDN_PLL_MASK, 0);
+ ret = wait_for_completion_timeout(&cs43130->pll_rdy,
+ msecs_to_jiffies(100));
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_PLL_RDY_INT_MASK,
+ 1 << CS43130_PLL_RDY_INT_SHIFT);
+ if (ret == 0) {
+ dev_err(codec->dev, "Timeout waiting for PLL_READY interrupt\n");
+ return -ETIMEDOUT;
+ }
+
+ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
+ CS43130_MCLK_SRC_SEL_MASK,
+ src << CS43130_MCLK_SRC_SEL_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
+ CS43130_MCLK_INT_MASK,
+ mclk_int_decoded << CS43130_MCLK_INT_SHIFT);
+ usleep_range(150, 200);
+ break;
+ case CS43130_MCLK_SRC_RCO:
+ cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
+
+ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
+ CS43130_MCLK_SRC_SEL_MASK,
+ src << CS43130_MCLK_SRC_SEL_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,
+ CS43130_MCLK_INT_MASK,
+ CS43130_MCLK_22P5 << CS43130_MCLK_INT_SHIFT);
+ usleep_range(150, 200);
+
+ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
+ CS43130_PDN_XTAL_MASK,
+ 1 << CS43130_PDN_XTAL_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,
+ CS43130_PDN_PLL_MASK,
+ 1 << CS43130_PDN_PLL_SHIFT);
+ break;
+ default:
+ dev_err(codec->dev, "Invalid MCLK source value\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct cs43130_bitwidth_map cs43130_bitwidth_table[] = {
+ {8, CS43130_SP_BIT_SIZE_8, CS43130_CH_BIT_SIZE_8},
+ {16, CS43130_SP_BIT_SIZE_16, CS43130_CH_BIT_SIZE_16},
+ {24, CS43130_SP_BIT_SIZE_24, CS43130_CH_BIT_SIZE_24},
+ {32, CS43130_SP_BIT_SIZE_32, CS43130_CH_BIT_SIZE_32},
+};
+
+static const struct cs43130_bitwidth_map *cs43130_get_bitwidth_table(
+ unsigned int bitwidth)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cs43130_bitwidth_table); i++) {
+ if (cs43130_bitwidth_table[i].bitwidth == bitwidth)
+ return &cs43130_bitwidth_table[i];
+ }
+
+ return NULL;
+}
+
+static int cs43130_set_bitwidth(int dai_id, unsigned int bitwidth_dai,
+ struct regmap *regmap)
+{
+ const struct cs43130_bitwidth_map *bw_map;
+
+ bw_map = cs43130_get_bitwidth_table(bitwidth_dai);
+ if (!bw_map)
+ return -EINVAL;
+
+ switch (dai_id) {
+ case CS43130_ASP_PCM_DAI:
+ case CS43130_ASP_DOP_DAI:
+ regmap_update_bits(regmap, CS43130_ASP_CH_1_SZ_EN,
+ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
+ regmap_update_bits(regmap, CS43130_ASP_CH_2_SZ_EN,
+ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
+ regmap_update_bits(regmap, CS43130_SP_BITSIZE,
+ CS43130_ASP_BITSIZE_MASK, bw_map->sp_bit);
+ break;
+ case CS43130_XSP_DOP_DAI:
+ regmap_update_bits(regmap, CS43130_XSP_CH_1_SZ_EN,
+ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
+ regmap_update_bits(regmap, CS43130_XSP_CH_2_SZ_EN,
+ CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);
+ regmap_update_bits(regmap, CS43130_SP_BITSIZE,
+ CS43130_XSP_BITSIZE_MASK, bw_map->sp_bit <<
+ CS43130_XSP_BITSIZE_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct cs43130_rate_map cs43130_rate_table[] = {
+ {32000, CS43130_ASP_SPRATE_32K},
+ {44100, CS43130_ASP_SPRATE_44_1K},
+ {48000, CS43130_ASP_SPRATE_48K},
+ {88200, CS43130_ASP_SPRATE_88_2K},
+ {96000, CS43130_ASP_SPRATE_96K},
+ {176400, CS43130_ASP_SPRATE_176_4K},
+ {192000, CS43130_ASP_SPRATE_192K},
+ {352800, CS43130_ASP_SPRATE_352_8K},
+ {384000, CS43130_ASP_SPRATE_384K},
+};
+
+static const struct cs43130_rate_map *cs43130_get_rate_table(int fs)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cs43130_rate_table); i++) {
+ if (cs43130_rate_table[i].fs == fs)
+ return &cs43130_rate_table[i];
+ }
+
+ return NULL;
+}
+
+static const struct cs43130_clk_gen *cs43130_get_clk_gen(int mclk_int, int fs,
+ const struct cs43130_clk_gen *clk_gen_table, int len_clk_gen_table)
+{
+ int i;
+
+ for (i = 0; i < len_clk_gen_table; i++) {
+ if (clk_gen_table[i].mclk_int == mclk_int &&
+ clk_gen_table[i].fs == fs)
+ return &clk_gen_table[i];
+ }
+
+ return NULL;
+}
+
+static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk,
+ struct snd_pcm_hw_params *params,
+ struct cs43130_private *cs43130)
+{
+ u16 frm_size;
+ u16 hi_size;
+ u8 frm_delay;
+ u8 frm_phase;
+ u8 frm_data;
+ u8 sclk_edge;
+ u8 lrck_edge;
+ u8 clk_data;
+ u8 loc_ch1;
+ u8 loc_ch2;
+ u8 dai_mode_val;
+ const struct cs43130_clk_gen *clk_gen;
+
+ switch (cs43130->dais[dai_id].dai_format) {
+ case SND_SOC_DAIFMT_I2S:
+ hi_size = bitwidth_sclk;
+ frm_delay = 2;
+ frm_phase = 0;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ hi_size = bitwidth_sclk;
+ frm_delay = 2;
+ frm_phase = 1;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ hi_size = 1;
+ frm_delay = 2;
+ frm_phase = 1;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ hi_size = 1;
+ frm_delay = 0;
+ frm_phase = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (cs43130->dais[dai_id].dai_mode) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ dai_mode_val = 0;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ dai_mode_val = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ frm_size = bitwidth_sclk * params_channels(params);
+ sclk_edge = 1;
+ lrck_edge = 0;
+ loc_ch1 = 0;
+ loc_ch2 = bitwidth_sclk * (params_channels(params) - 1);
+
+ frm_data = frm_delay & CS43130_SP_FSD_MASK;
+ frm_data |= (frm_phase << CS43130_SP_STP_SHIFT) & CS43130_SP_STP_MASK;
+
+ clk_data = lrck_edge & CS43130_SP_LCPOL_IN_MASK;
+ clk_data |= (lrck_edge << CS43130_SP_LCPOL_OUT_SHIFT) &
+ CS43130_SP_LCPOL_OUT_MASK;
+ clk_data |= (sclk_edge << CS43130_SP_SCPOL_IN_SHIFT) &
+ CS43130_SP_SCPOL_IN_MASK;
+ clk_data |= (sclk_edge << CS43130_SP_SCPOL_OUT_SHIFT) &
+ CS43130_SP_SCPOL_OUT_MASK;
+ clk_data |= (dai_mode_val << CS43130_SP_MODE_SHIFT) &
+ CS43130_SP_MODE_MASK;
+
+ switch (dai_id) {
+ case CS43130_ASP_PCM_DAI:
+ case CS43130_ASP_DOP_DAI:
+ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_1,
+ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
+ CS43130_SP_LCPR_LSB_DATA_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_2,
+ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
+ CS43130_SP_LCPR_MSB_DATA_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_1,
+ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
+ CS43130_SP_LCHI_LSB_DATA_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_2,
+ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
+ CS43130_SP_LCHI_MSB_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_ASP_FRAME_CONF, frm_data);
+ regmap_write(cs43130->regmap, CS43130_ASP_CH_1_LOC, loc_ch1);
+ regmap_write(cs43130->regmap, CS43130_ASP_CH_2_LOC, loc_ch2);
+ regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_1_SZ_EN,
+ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_2_SZ_EN,
+ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_ASP_CLOCK_CONF, clk_data);
+ break;
+ case CS43130_XSP_DOP_DAI:
+ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_1,
+ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
+ CS43130_SP_LCPR_LSB_DATA_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_2,
+ CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>
+ CS43130_SP_LCPR_MSB_DATA_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_1,
+ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
+ CS43130_SP_LCHI_LSB_DATA_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_2,
+ CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>
+ CS43130_SP_LCHI_MSB_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_XSP_FRAME_CONF, frm_data);
+ regmap_write(cs43130->regmap, CS43130_XSP_CH_1_LOC, loc_ch1);
+ regmap_write(cs43130->regmap, CS43130_XSP_CH_2_LOC, loc_ch2);
+ regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_1_SZ_EN,
+ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_2_SZ_EN,
+ CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_XSP_CLOCK_CONF, clk_data);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (frm_size) {
+ case 16:
+ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
+ params_rate(params),
+ cs43130_16_clk_gen,
+ ARRAY_SIZE(cs43130_16_clk_gen));
+ break;
+ case 32:
+ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
+ params_rate(params),
+ cs43130_32_clk_gen,
+ ARRAY_SIZE(cs43130_32_clk_gen));
+ break;
+ case 48:
+ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
+ params_rate(params),
+ cs43130_48_clk_gen,
+ ARRAY_SIZE(cs43130_48_clk_gen));
+ break;
+ case 64:
+ clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,
+ params_rate(params),
+ cs43130_64_clk_gen,
+ ARRAY_SIZE(cs43130_64_clk_gen));
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!clk_gen)
+ return -EINVAL;
+
+ switch (dai_id) {
+ case CS43130_ASP_PCM_DAI:
+ case CS43130_ASP_DOP_DAI:
+ regmap_write(cs43130->regmap, CS43130_ASP_DEN_1,
+ (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >>
+ CS43130_SP_M_LSB_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_ASP_DEN_2,
+ (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >>
+ CS43130_SP_M_MSB_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_ASP_NUM_1,
+ (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >>
+ CS43130_SP_N_LSB_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_ASP_NUM_2,
+ (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >>
+ CS43130_SP_N_MSB_DATA_SHIFT);
+ break;
+ case CS43130_XSP_DOP_DAI:
+ regmap_write(cs43130->regmap, CS43130_XSP_DEN_1,
+ (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >>
+ CS43130_SP_M_LSB_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_XSP_DEN_2,
+ (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >>
+ CS43130_SP_M_MSB_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_XSP_NUM_1,
+ (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >>
+ CS43130_SP_N_LSB_DATA_SHIFT);
+ regmap_write(cs43130->regmap, CS43130_XSP_NUM_2,
+ (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >>
+ CS43130_SP_N_MSB_DATA_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int cs43130_pcm_dsd_mix(bool en, struct regmap *regmap)
+{
+ if (en) {
+ regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,
+ CS43130_MIX_PCM_PREP_MASK,
+ 1 << CS43130_MIX_PCM_PREP_SHIFT);
+ usleep_range(6000, 6050);
+ regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,
+ CS43130_MIX_PCM_DSD_MASK,
+ 1 << CS43130_MIX_PCM_DSD_SHIFT);
+ } else {
+ regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,
+ CS43130_MIX_PCM_DSD_MASK,
+ 0 << CS43130_MIX_PCM_DSD_SHIFT);
+ usleep_range(1600, 1650);
+ regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,
+ CS43130_MIX_PCM_PREP_MASK,
+ 0 << CS43130_MIX_PCM_PREP_SHIFT);
+ }
+
+ return 0;
+}
+
+static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+ unsigned int required_clk;
+ u8 dsd_speed;
+
+ mutex_lock(&cs43130->clk_mutex);
+ if (!cs43130->clk_req) {
+ /* no DAI is currently using clk */
+ if (!(CS43130_MCLK_22M % params_rate(params)))
+ required_clk = CS43130_MCLK_22M;
+ else
+ required_clk = CS43130_MCLK_24M;
+
+ cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk);
+ if (cs43130->pll_bypass)
+ cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+ else
+ cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+ }
+
+ cs43130->clk_req++;
+ if (cs43130->clk_req == 2)
+ cs43130_pcm_dsd_mix(true, cs43130->regmap);
+ mutex_unlock(&cs43130->clk_mutex);
+
+ switch (params_rate(params)) {
+ case 176400:
+ dsd_speed = 0;
+ break;
+ case 352800:
+ dsd_speed = 1;
+ break;
+ default:
+ dev_err(codec->dev, "Rate(%u) not supported\n",
+ params_rate(params));
+ return -EINVAL;
+ }
+
+ if (cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM)
+ regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG,
+ CS43130_DSD_MASTER, CS43130_DSD_MASTER);
+ else
+ regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG,
+ CS43130_DSD_MASTER, 0);
+
+ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
+ CS43130_DSD_SPEED_MASK,
+ dsd_speed << CS43130_DSD_SPEED_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
+ CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_DSD <<
+ CS43130_DSD_SRC_SHIFT);
+
+ return 0;
+}
+
+static int cs43130_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+ const struct cs43130_rate_map *rate_map;
+ unsigned int sclk = cs43130->dais[dai->id].sclk;
+ unsigned int bitwidth_sclk;
+ unsigned int bitwidth_dai = (unsigned int)(params_width(params));
+ unsigned int required_clk;
+ u8 dsd_speed;
+
+ mutex_lock(&cs43130->clk_mutex);
+ if (!cs43130->clk_req) {
+ /* no DAI is currently using clk */
+ if (!(CS43130_MCLK_22M % params_rate(params)))
+ required_clk = CS43130_MCLK_22M;
+ else
+ required_clk = CS43130_MCLK_24M;
+
+ cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk);
+ if (cs43130->pll_bypass)
+ cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+ else
+ cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+ }
+
+ cs43130->clk_req++;
+ if (cs43130->clk_req == 2)
+ cs43130_pcm_dsd_mix(true, cs43130->regmap);
+ mutex_unlock(&cs43130->clk_mutex);
+
+ switch (dai->id) {
+ case CS43130_ASP_DOP_DAI:
+ case CS43130_XSP_DOP_DAI:
+ /* DoP bitwidth is always 24-bit */
+ bitwidth_dai = 24;
+ sclk = params_rate(params) * bitwidth_dai *
+ params_channels(params);
+
+ switch (params_rate(params)) {
+ case 176400:
+ dsd_speed = 0;
+ break;
+ case 352800:
+ dsd_speed = 1;
+ break;
+ default:
+ dev_err(codec->dev, "Rate(%u) not supported\n",
+ params_rate(params));
+ return -EINVAL;
+ }
+
+ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
+ CS43130_DSD_SPEED_MASK,
+ dsd_speed << CS43130_DSD_SPEED_SHIFT);
+ break;
+ case CS43130_ASP_PCM_DAI:
+ rate_map = cs43130_get_rate_table(params_rate(params));
+ if (!rate_map)
+ return -EINVAL;
+
+ regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val);
+ break;
+ default:
+ dev_err(codec->dev, "Invalid DAI (%d)\n", dai->id);
+ return -EINVAL;
+ }
+
+ switch (dai->id) {
+ case CS43130_ASP_DOP_DAI:
+ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
+ CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_ASP <<
+ CS43130_DSD_SRC_SHIFT);
+ break;
+ case CS43130_XSP_DOP_DAI:
+ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
+ CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP <<
+ CS43130_DSD_SRC_SHIFT);
+ }
+
+ if (!sclk && cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM)
+ /* Calculate SCLK in master mode if unassigned */
+ sclk = params_rate(params) * bitwidth_dai *
+ params_channels(params);
+
+ if (!sclk) {
+ /* at this point, SCLK must be set */
+ dev_err(codec->dev, "SCLK freq is not set\n");
+ return -EINVAL;
+ }
+
+ bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params);
+ if (bitwidth_sclk < bitwidth_dai) {
+ dev_err(codec->dev, "Format not supported: SCLK freq is too low\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev,
+ "sclk = %u, fs = %d, bitwidth_dai = %u\n",
+ sclk, params_rate(params), bitwidth_dai);
+
+ dev_dbg(codec->dev,
+ "bitwidth_sclk = %u, num_ch = %u\n",
+ bitwidth_sclk, params_channels(params));
+
+ cs43130_set_bitwidth(dai->id, bitwidth_dai, cs43130->regmap);
+ cs43130_set_sp_fmt(dai->id, bitwidth_sclk, params, cs43130);
+
+ return 0;
+}
+
+static int cs43130_hw_free(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&cs43130->clk_mutex);
+ cs43130->clk_req--;
+ if (!cs43130->clk_req) {
+ /* no DAI is currently using clk */
+ cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO);
+ cs43130_pcm_dsd_mix(false, cs43130->regmap);
+ }
+ mutex_unlock(&cs43130->clk_mutex);
+
+ return 0;
+}
+
+static const DECLARE_TLV_DB_SCALE(pcm_vol_tlv, -12750, 50, 1);
+
+static const char * const pcm_ch_text[] = {
+ "Left-Right Ch",
+ "Left-Left Ch",
+ "Right-Left Ch",
+ "Right-Right Ch",
+};
+
+static const struct reg_sequence pcm_ch_en_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {0x180005, 0x8C},
+ {0x180007, 0xAB},
+ {0x180015, 0x31},
+ {0x180017, 0xB2},
+ {0x180025, 0x30},
+ {0x180027, 0x84},
+ {0x180035, 0x9C},
+ {0x180037, 0xAE},
+ {0x18000D, 0x24},
+ {0x18000F, 0xA3},
+ {0x18001D, 0x05},
+ {0x18001F, 0xD4},
+ {0x18002D, 0x0B},
+ {0x18002F, 0xC7},
+ {0x18003D, 0x71},
+ {0x18003F, 0xE7},
+ {CS43130_DXD1, 0},
+};
+
+static const struct reg_sequence pcm_ch_dis_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {0x180005, 0x24},
+ {0x180007, 0xA3},
+ {0x180015, 0x05},
+ {0x180017, 0xD4},
+ {0x180025, 0x0B},
+ {0x180027, 0xC7},
+ {0x180035, 0x71},
+ {0x180037, 0xE7},
+ {0x18000D, 0x8C},
+ {0x18000F, 0xAB},
+ {0x18001D, 0x31},
+ {0x18001F, 0xB2},
+ {0x18002D, 0x30},
+ {0x18002F, 0x84},
+ {0x18003D, 0x9C},
+ {0x18003F, 0xAE},
+ {CS43130_DXD1, 0},
+};
+
+static int cs43130_pcm_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return snd_soc_get_enum_double(kcontrol, ucontrol);
+}
+
+static int cs43130_pcm_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+ unsigned int val;
+
+ if (item[0] >= e->items)
+ return -EINVAL;
+ val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
+
+ switch (cs43130->dev_id) {
+ case CS43131_CHIP_ID:
+ case CS43198_CHIP_ID:
+ if (val >= 2)
+ regmap_multi_reg_write(cs43130->regmap, pcm_ch_en_seq,
+ ARRAY_SIZE(pcm_ch_en_seq));
+ else
+ regmap_multi_reg_write(cs43130->regmap, pcm_ch_dis_seq,
+ ARRAY_SIZE(pcm_ch_dis_seq));
+ }
+
+ return snd_soc_put_enum_double(kcontrol, ucontrol);
+}
+
+static SOC_ENUM_SINGLE_DECL(pcm_ch_enum, CS43130_PCM_PATH_CTL_2, 0,
+ pcm_ch_text);
+
+static const char * const pcm_spd_texts[] = {
+ "Fast",
+ "Slow",
+};
+
+static SOC_ENUM_SINGLE_DECL(pcm_spd_enum, CS43130_PCM_FILT_OPT, 7,
+ pcm_spd_texts);
+
+static const char * const dsd_texts[] = {
+ "Off",
+ "BCKA Mode",
+ "BCKD Mode",
+};
+
+static const unsigned int dsd_values[] = {
+ CS43130_DSD_SRC_DSD,
+ CS43130_DSD_SRC_ASP,
+ CS43130_DSD_SRC_XSP,
+};
+
+static SOC_VALUE_ENUM_SINGLE_DECL(dsd_enum, CS43130_DSD_INT_CFG, 0, 0x03,
+ dsd_texts, dsd_values);
+
+static const struct snd_kcontrol_new cs43130_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("Master Playback Volume",
+ CS43130_PCM_VOL_A, CS43130_PCM_VOL_B, 0, 0xFF, 1,
+ pcm_vol_tlv),
+ SOC_DOUBLE_R_TLV("Master DSD Playback Volume",
+ CS43130_DSD_VOL_A, CS43130_DSD_VOL_B, 0, 0xFF, 1,
+ pcm_vol_tlv),
+ SOC_ENUM_EXT("PCM Ch Select", pcm_ch_enum, cs43130_pcm_ch_get,
+ cs43130_pcm_ch_put),
+ SOC_ENUM("PCM Filter Speed", pcm_spd_enum),
+ SOC_SINGLE("PCM Phase Compensation", CS43130_PCM_FILT_OPT, 6, 1, 0),
+ SOC_SINGLE("PCM Nonoversample Emulate", CS43130_PCM_FILT_OPT, 5, 1, 0),
+ SOC_SINGLE("PCM High-pass Filter", CS43130_PCM_FILT_OPT, 1, 1, 0),
+ SOC_SINGLE("PCM De-emphasis Filter", CS43130_PCM_FILT_OPT, 0, 1, 0),
+ SOC_ENUM("DSD Phase Modulation", dsd_enum),
+};
+
+static const struct reg_sequence pcm_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD7, 0x01},
+ {CS43130_DXD8, 0},
+ {CS43130_DXD9, 0x01},
+ {CS43130_DXD3, 0x12},
+ {CS43130_DXD4, 0},
+ {CS43130_DXD10, 0x28},
+ {CS43130_DXD11, 0x28},
+ {CS43130_DXD1, 0},
+};
+
+static const struct reg_sequence dsd_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD7, 0x01},
+ {CS43130_DXD8, 0},
+ {CS43130_DXD9, 0x01},
+ {CS43130_DXD3, 0x12},
+ {CS43130_DXD4, 0},
+ {CS43130_DXD10, 0x1E},
+ {CS43130_DXD11, 0x20},
+ {CS43130_DXD1, 0},
+};
+
+static const struct reg_sequence pop_free_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD12, 0x0A},
+ {CS43130_DXD1, 0},
+};
+
+static const struct reg_sequence pop_free_seq2[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD13, 0x20},
+ {CS43130_DXD1, 0},
+};
+
+static const struct reg_sequence mute_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD3, 0x12},
+ {CS43130_DXD5, 0x02},
+ {CS43130_DXD4, 0x12},
+ {CS43130_DXD1, 0},
+};
+
+static const struct reg_sequence unmute_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD3, 0x10},
+ {CS43130_DXD5, 0},
+ {CS43130_DXD4, 0x16},
+ {CS43130_DXD1, 0},
+};
+
+static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, dsd_seq,
+ ARRAY_SIZE(dsd_seq));
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_1,
+ CS43130_MUTE_MASK, 0);
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, unmute_seq,
+ ARRAY_SIZE(unmute_seq));
+ }
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, mute_seq,
+ ARRAY_SIZE(mute_seq));
+ regmap_update_bits(cs43130->regmap,
+ CS43130_DSD_PATH_CTL_1,
+ CS43130_MUTE_MASK, CS43130_MUTE_EN);
+ /*
+ * DSD Power Down Sequence
+ * According to Design, 130ms is preferred.
+ */
+ msleep(130);
+ break;
+ case CS43131_CHIP_ID:
+ case CS43198_CHIP_ID:
+ regmap_update_bits(cs43130->regmap,
+ CS43130_DSD_PATH_CTL_1,
+ CS43130_MUTE_MASK, CS43130_MUTE_EN);
+ }
+ break;
+ default:
+ dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, pcm_seq,
+ ARRAY_SIZE(pcm_seq));
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ regmap_update_bits(cs43130->regmap, CS43130_PCM_PATH_CTL_1,
+ CS43130_MUTE_MASK, 0);
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, unmute_seq,
+ ARRAY_SIZE(unmute_seq));
+ }
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, mute_seq,
+ ARRAY_SIZE(mute_seq));
+ regmap_update_bits(cs43130->regmap,
+ CS43130_PCM_PATH_CTL_1,
+ CS43130_MUTE_MASK, CS43130_MUTE_EN);
+ /*
+ * PCM Power Down Sequence
+ * According to Design, 130ms is preferred.
+ */
+ msleep(130);
+ break;
+ case CS43131_CHIP_ID:
+ case CS43198_CHIP_ID:
+ regmap_update_bits(cs43130->regmap,
+ CS43130_PCM_PATH_CTL_1,
+ CS43130_MUTE_MASK, CS43130_MUTE_EN);
+ }
+ break;
+ default:
+ dev_err(codec->dev, "Invalid event = 0x%x\n", event);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct reg_sequence dac_postpmu_seq[] = {
+ {CS43130_DXD9, 0x0C},
+ {CS43130_DXD3, 0x10},
+ {CS43130_DXD4, 0x20},
+};
+
+static const struct reg_sequence dac_postpmd_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD6, 0x01},
+ {CS43130_DXD1, 0},
+};
+
+static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, pop_free_seq,
+ ARRAY_SIZE(pop_free_seq));
+ break;
+ case CS43131_CHIP_ID:
+ case CS43198_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, pop_free_seq2,
+ ARRAY_SIZE(pop_free_seq2));
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(10000, 10050);
+
+ regmap_write(cs43130->regmap, CS43130_DXD1, 0x99);
+
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, dac_postpmu_seq,
+ ARRAY_SIZE(dac_postpmu_seq));
+ /*
+ * Per datasheet, Sec. PCM Power-Up Sequence.
+ * According to Design, CS43130_DXD12 must be 0 to meet
+ * THDN and Dynamic Range spec.
+ */
+ msleep(1000);
+ regmap_write(cs43130->regmap, CS43130_DXD12, 0);
+ break;
+ case CS43131_CHIP_ID:
+ case CS43198_CHIP_ID:
+ usleep_range(12000, 12010);
+ regmap_write(cs43130->regmap, CS43130_DXD13, 0);
+ }
+
+ regmap_write(cs43130->regmap, CS43130_DXD1, 0);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ regmap_multi_reg_write(cs43130->regmap, dac_postpmd_seq,
+ ARRAY_SIZE(dac_postpmd_seq));
+ }
+ break;
+ default:
+ dev_err(codec->dev, "Invalid DAC event = 0x%x\n", event);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct reg_sequence hpin_prepmd_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD15, 0x64},
+ {CS43130_DXD14, 0},
+ {CS43130_DXD2, 0},
+ {CS43130_DXD1, 0},
+};
+
+static const struct reg_sequence hpin_postpmu_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD2, 1},
+ {CS43130_DXD14, 0xDC},
+ {CS43130_DXD15, 0xE4},
+ {CS43130_DXD1, 0},
+};
+
+static int cs43130_hpin_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ regmap_multi_reg_write(cs43130->regmap, hpin_prepmd_seq,
+ ARRAY_SIZE(hpin_prepmd_seq));
+ break;
+ case SND_SOC_DAPM_PRE_PMU:
+ regmap_multi_reg_write(cs43130->regmap, hpin_postpmu_seq,
+ ARRAY_SIZE(hpin_postpmu_seq));
+ break;
+ default:
+ dev_err(codec->dev, "Invalid HPIN event = 0x%x\n", event);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget digital_hp_widgets[] = {
+ SND_SOC_DAPM_OUTPUT("HPOUTA"),
+ SND_SOC_DAPM_OUTPUT("HPOUTB"),
+
+ SND_SOC_DAPM_AIF_IN_E("ASPIN PCM", NULL, 0, CS43130_PWDN_CTL,
+ CS43130_PDN_ASP_SHIFT, 1, cs43130_pcm_event,
+ (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD)),
+
+ SND_SOC_DAPM_AIF_IN_E("ASPIN DoP", NULL, 0, CS43130_PWDN_CTL,
+ CS43130_PDN_ASP_SHIFT, 1, cs43130_dsd_event,
+ (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD)),
+
+ SND_SOC_DAPM_AIF_IN_E("XSPIN DoP", NULL, 0, CS43130_PWDN_CTL,
+ CS43130_PDN_XSP_SHIFT, 1, cs43130_dsd_event,
+ (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD)),
+
+ SND_SOC_DAPM_AIF_IN_E("XSPIN DSD", NULL, 0, CS43130_PWDN_CTL,
+ CS43130_PDN_DSDIF_SHIFT, 1, cs43130_dsd_event,
+ (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD)),
+
+ SND_SOC_DAPM_DAC("DSD", NULL, CS43130_DSD_PATH_CTL_2,
+ CS43130_DSD_EN_SHIFT, 0),
+
+ SND_SOC_DAPM_DAC_E("HiFi DAC", NULL, CS43130_PWDN_CTL,
+ CS43130_PDN_HP_SHIFT, 1, cs43130_dac_event,
+ (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD)),
+};
+
+static const struct snd_soc_dapm_widget analog_hp_widgets[] = {
+ SND_SOC_DAPM_DAC_E("Analog Playback", NULL, CS43130_HP_OUT_CTL_1,
+ CS43130_HP_IN_EN_SHIFT, 0, cs43130_hpin_event,
+ (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)),
+};
+
+static struct snd_soc_dapm_widget all_hp_widgets[
+ ARRAY_SIZE(digital_hp_widgets) +
+ ARRAY_SIZE(analog_hp_widgets)];
+
+static const struct snd_soc_dapm_route digital_hp_routes[] = {
+ {"ASPIN PCM", NULL, "ASP PCM Playback"},
+ {"ASPIN DoP", NULL, "ASP DoP Playback"},
+ {"XSPIN DoP", NULL, "XSP DoP Playback"},
+ {"XSPIN DSD", NULL, "XSP DSD Playback"},
+ {"DSD", NULL, "ASPIN DoP"},
+ {"DSD", NULL, "XSPIN DoP"},
+ {"DSD", NULL, "XSPIN DSD"},
+ {"HiFi DAC", NULL, "ASPIN PCM"},
+ {"HiFi DAC", NULL, "DSD"},
+ {"HPOUTA", NULL, "HiFi DAC"},
+ {"HPOUTB", NULL, "HiFi DAC"},
+};
+
+static const struct snd_soc_dapm_route analog_hp_routes[] = {
+ {"HPOUTA", NULL, "Analog Playback"},
+ {"HPOUTB", NULL, "Analog Playback"},
+};
+
+static struct snd_soc_dapm_route all_hp_routes[
+ ARRAY_SIZE(digital_hp_routes) +
+ ARRAY_SIZE(analog_hp_routes)];
+
+static const unsigned int cs43130_asp_src_rates[] = {
+ 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000
+};
+
+static const struct snd_pcm_hw_constraint_list cs43130_asp_constraints = {
+ .count = ARRAY_SIZE(cs43130_asp_src_rates),
+ .list = cs43130_asp_src_rates,
+};
+
+static int cs43130_pcm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ return snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &cs43130_asp_constraints);
+}
+
+static const unsigned int cs43130_dop_src_rates[] = {
+ 176400, 352800,
+};
+
+static const struct snd_pcm_hw_constraint_list cs43130_dop_constraints = {
+ .count = ARRAY_SIZE(cs43130_dop_src_rates),
+ .list = cs43130_dop_src_rates,
+};
+
+static int cs43130_dop_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ return snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &cs43130_dop_constraints);
+}
+
+static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ default:
+ dev_err(codec->dev, "unsupported mode\n");
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_LEFT_J;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_A;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_B;
+ break;
+ default:
+ dev_err(codec->dev,
+ "unsupported audio format\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "dai_id = %d, dai_mode = %u, dai_format = %u\n",
+ codec_dai->id,
+ cs43130->dais[codec_dai->id].dai_mode,
+ cs43130->dais[codec_dai->id].dai_format);
+
+ return 0;
+}
+
+static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ default:
+ dev_err(codec->dev, "Unsupported DAI format.\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "dai_mode = 0x%x\n",
+ cs43130->dais[codec_dai->id].dai_mode);
+
+ return 0;
+}
+
+static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = codec_dai->codec;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ cs43130->dais[codec_dai->id].sclk = freq;
+ dev_dbg(codec->dev, "dai_id = %d, sclk = %u\n", codec_dai->id,
+ cs43130->dais[codec_dai->id].sclk);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops cs43130_pcm_ops = {
+ .startup = cs43130_pcm_startup,
+ .hw_params = cs43130_hw_params,
+ .hw_free = cs43130_hw_free,
+ .set_sysclk = cs43130_set_sysclk,
+ .set_fmt = cs43130_pcm_set_fmt,
+};
+
+static const struct snd_soc_dai_ops cs43130_dop_ops = {
+ .startup = cs43130_dop_startup,
+ .hw_params = cs43130_hw_params,
+ .hw_free = cs43130_hw_free,
+ .set_sysclk = cs43130_set_sysclk,
+ .set_fmt = cs43130_pcm_set_fmt,
+};
+
+static const struct snd_soc_dai_ops cs43130_dsd_ops = {
+ .startup = cs43130_dop_startup,
+ .hw_params = cs43130_dsd_hw_params,
+ .hw_free = cs43130_hw_free,
+ .set_fmt = cs43130_dsd_set_fmt,
+};
+
+static struct snd_soc_dai_driver cs43130_dai[] = {
+ {
+ .name = "cs43130-asp-pcm",
+ .id = CS43130_ASP_PCM_DAI,
+ .playback = {
+ .stream_name = "ASP PCM Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = CS43130_PCM_FORMATS,
+ },
+ .ops = &cs43130_pcm_ops,
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "cs43130-asp-dop",
+ .id = CS43130_ASP_DOP_DAI,
+ .playback = {
+ .stream_name = "ASP DoP Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = CS43130_DOP_FORMATS,
+ },
+ .ops = &cs43130_dop_ops,
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "cs43130-xsp-dop",
+ .id = CS43130_XSP_DOP_DAI,
+ .playback = {
+ .stream_name = "XSP DoP Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = CS43130_DOP_FORMATS,
+ },
+ .ops = &cs43130_dop_ops,
+ .symmetric_rates = 1,
+ },
+ {
+ .name = "cs43130-xsp-dsd",
+ .id = CS43130_XSP_DSD_DAI,
+ .playback = {
+ .stream_name = "XSP DSD Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .formats = CS43130_DOP_FORMATS,
+ },
+ .ops = &cs43130_dsd_ops,
+ },
+
+};
+
+static int cs43130_codec_set_sysclk(struct snd_soc_codec *codec,
+ int clk_id, int source, unsigned int freq,
+ int dir)
+{
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",
+ clk_id, source, freq, dir);
+
+ switch (freq) {
+ case CS43130_MCLK_22M:
+ case CS43130_MCLK_24M:
+ cs43130->mclk = freq;
+ break;
+ default:
+ dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", freq);
+ return -EINVAL;
+ }
+
+ if (source == CS43130_MCLK_SRC_EXT) {
+ cs43130->pll_bypass = true;
+ } else {
+ dev_err(codec->dev, "Invalid MCLK source\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline u16 cs43130_get_ac_reg_val(u16 ac_freq)
+{
+ /* AC freq is counted in 5.94Hz step. */
+ return ac_freq / 6;
+}
+
+static int cs43130_show_dc(struct device *dev, char *buf, u8 ch)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cs43130_private *cs43130 = i2c_get_clientdata(client);
+
+ if (!cs43130->hpload_done)
+ return scnprintf(buf, PAGE_SIZE, "NO_HPLOAD\n");
+ else
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ cs43130->hpload_dc[ch]);
+}
+
+static ssize_t cs43130_show_dc_l(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return cs43130_show_dc(dev, buf, HP_LEFT);
+}
+
+static ssize_t cs43130_show_dc_r(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return cs43130_show_dc(dev, buf, HP_RIGHT);
+}
+
+static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = {
+ 24,
+ 43,
+ 93,
+ 200,
+ 431,
+ 928,
+ 2000,
+ 4309,
+ 9283,
+ 20000,
+};
+
+static int cs43130_show_ac(struct device *dev, char *buf, u8 ch)
+{
+ int i, j = 0, tmp;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct cs43130_private *cs43130 = i2c_get_clientdata(client);
+
+ if (cs43130->hpload_done && cs43130->ac_meas) {
+ for (i = 0; i < ARRAY_SIZE(cs43130_ac_freq); i++) {
+ tmp = scnprintf(buf + j, PAGE_SIZE - j, "%u\n",
+ cs43130->hpload_ac[i][ch]);
+ if (!tmp)
+ break;
+
+ j += tmp;
+ }
+
+ return j;
+ } else {
+ return scnprintf(buf, PAGE_SIZE, "NO_HPLOAD\n");
+ }
+}
+
+static ssize_t cs43130_show_ac_l(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return cs43130_show_ac(dev, buf, HP_LEFT);
+}
+
+static ssize_t cs43130_show_ac_r(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return cs43130_show_ac(dev, buf, HP_RIGHT);
+}
+
+static DEVICE_ATTR(hpload_dc_l, S_IRUGO, cs43130_show_dc_l, NULL);
+static DEVICE_ATTR(hpload_dc_r, S_IRUGO, cs43130_show_dc_r, NULL);
+static DEVICE_ATTR(hpload_ac_l, S_IRUGO, cs43130_show_ac_l, NULL);
+static DEVICE_ATTR(hpload_ac_r, S_IRUGO, cs43130_show_ac_r, NULL);
+
+static struct reg_sequence hp_en_cal_seq[] = {
+ {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},
+ {CS43130_HP_MEAS_LOAD_1, 0},
+ {CS43130_HP_MEAS_LOAD_2, 0},
+ {CS43130_INT_MASK_4, 0},
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD16, 0xBB},
+ {CS43130_DXD12, 0x01},
+ {CS43130_DXD19, 0xCB},
+ {CS43130_DXD17, 0x95},
+ {CS43130_DXD18, 0x0B},
+ {CS43130_DXD1, 0},
+ {CS43130_HP_LOAD_1, 0x80},
+};
+
+static struct reg_sequence hp_en_cal_seq2[] = {
+ {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},
+ {CS43130_HP_MEAS_LOAD_1, 0},
+ {CS43130_HP_MEAS_LOAD_2, 0},
+ {CS43130_INT_MASK_4, 0},
+ {CS43130_HP_LOAD_1, 0x80},
+};
+
+static struct reg_sequence hp_dis_cal_seq[] = {
+ {CS43130_HP_LOAD_1, 0x80},
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD12, 0},
+ {CS43130_DXD1, 0},
+ {CS43130_HP_LOAD_1, 0},
+};
+
+static struct reg_sequence hp_dis_cal_seq2[] = {
+ {CS43130_HP_LOAD_1, 0x80},
+ {CS43130_HP_LOAD_1, 0},
+};
+
+static struct reg_sequence hp_dc_ch_l_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD19, 0x0A},
+ {CS43130_DXD17, 0x93},
+ {CS43130_DXD18, 0x0A},
+ {CS43130_DXD1, 0},
+ {CS43130_HP_LOAD_1, 0x80},
+ {CS43130_HP_LOAD_1, 0x81},
+};
+
+static struct reg_sequence hp_dc_ch_l_seq2[] = {
+ {CS43130_HP_LOAD_1, 0x80},
+ {CS43130_HP_LOAD_1, 0x81},
+};
+
+static struct reg_sequence hp_dc_ch_r_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD19, 0x8A},
+ {CS43130_DXD17, 0x15},
+ {CS43130_DXD18, 0x06},
+ {CS43130_DXD1, 0},
+ {CS43130_HP_LOAD_1, 0x90},
+ {CS43130_HP_LOAD_1, 0x91},
+};
+
+static struct reg_sequence hp_dc_ch_r_seq2[] = {
+ {CS43130_HP_LOAD_1, 0x90},
+ {CS43130_HP_LOAD_1, 0x91},
+};
+
+static struct reg_sequence hp_ac_ch_l_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD19, 0x0A},
+ {CS43130_DXD17, 0x93},
+ {CS43130_DXD18, 0x0A},
+ {CS43130_DXD1, 0},
+ {CS43130_HP_LOAD_1, 0x80},
+ {CS43130_HP_LOAD_1, 0x82},
+};
+
+static struct reg_sequence hp_ac_ch_l_seq2[] = {
+ {CS43130_HP_LOAD_1, 0x80},
+ {CS43130_HP_LOAD_1, 0x82},
+};
+
+static struct reg_sequence hp_ac_ch_r_seq[] = {
+ {CS43130_DXD1, 0x99},
+ {CS43130_DXD19, 0x8A},
+ {CS43130_DXD17, 0x15},
+ {CS43130_DXD18, 0x06},
+ {CS43130_DXD1, 0},
+ {CS43130_HP_LOAD_1, 0x90},
+ {CS43130_HP_LOAD_1, 0x92},
+};
+
+static struct reg_sequence hp_ac_ch_r_seq2[] = {
+ {CS43130_HP_LOAD_1, 0x90},
+ {CS43130_HP_LOAD_1, 0x92},
+};
+
+static struct reg_sequence hp_cln_seq[] = {
+ {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},
+ {CS43130_HP_MEAS_LOAD_1, 0},
+ {CS43130_HP_MEAS_LOAD_2, 0},
+};
+
+struct reg_sequences {
+ struct reg_sequence *seq;
+ int size;
+ unsigned int msk;
+};
+
+static struct reg_sequences hpload_seq1[] = {
+ {
+ .seq = hp_en_cal_seq,
+ .size = ARRAY_SIZE(hp_en_cal_seq),
+ .msk = CS43130_HPLOAD_ON_INT,
+ },
+ {
+ .seq = hp_dc_ch_l_seq,
+ .size = ARRAY_SIZE(hp_dc_ch_l_seq),
+ .msk = CS43130_HPLOAD_DC_INT,
+ },
+ {
+ .seq = hp_ac_ch_l_seq,
+ .size = ARRAY_SIZE(hp_ac_ch_l_seq),
+ .msk = CS43130_HPLOAD_AC_INT,
+ },
+ {
+ .seq = hp_dis_cal_seq,
+ .size = ARRAY_SIZE(hp_dis_cal_seq),
+ .msk = CS43130_HPLOAD_OFF_INT,
+ },
+ {
+ .seq = hp_en_cal_seq,
+ .size = ARRAY_SIZE(hp_en_cal_seq),
+ .msk = CS43130_HPLOAD_ON_INT,
+ },
+ {
+ .seq = hp_dc_ch_r_seq,
+ .size = ARRAY_SIZE(hp_dc_ch_r_seq),
+ .msk = CS43130_HPLOAD_DC_INT,
+ },
+ {
+ .seq = hp_ac_ch_r_seq,
+ .size = ARRAY_SIZE(hp_ac_ch_r_seq),
+ .msk = CS43130_HPLOAD_AC_INT,
+ },
+};
+
+static struct reg_sequences hpload_seq2[] = {
+ {
+ .seq = hp_en_cal_seq2,
+ .size = ARRAY_SIZE(hp_en_cal_seq2),
+ .msk = CS43130_HPLOAD_ON_INT,
+ },
+ {
+ .seq = hp_dc_ch_l_seq2,
+ .size = ARRAY_SIZE(hp_dc_ch_l_seq2),
+ .msk = CS43130_HPLOAD_DC_INT,
+ },
+ {
+ .seq = hp_ac_ch_l_seq2,
+ .size = ARRAY_SIZE(hp_ac_ch_l_seq2),
+ .msk = CS43130_HPLOAD_AC_INT,
+ },
+ {
+ .seq = hp_dis_cal_seq2,
+ .size = ARRAY_SIZE(hp_dis_cal_seq2),
+ .msk = CS43130_HPLOAD_OFF_INT,
+ },
+ {
+ .seq = hp_en_cal_seq2,
+ .size = ARRAY_SIZE(hp_en_cal_seq2),
+ .msk = CS43130_HPLOAD_ON_INT,
+ },
+ {
+ .seq = hp_dc_ch_r_seq2,
+ .size = ARRAY_SIZE(hp_dc_ch_r_seq2),
+ .msk = CS43130_HPLOAD_DC_INT,
+ },
+ {
+ .seq = hp_ac_ch_r_seq2,
+ .size = ARRAY_SIZE(hp_ac_ch_r_seq2),
+ .msk = CS43130_HPLOAD_AC_INT,
+ },
+};
+
+static int cs43130_update_hpload(unsigned int msk, int ac_idx,
+ struct cs43130_private *cs43130)
+{
+ bool left_ch = true;
+ unsigned int reg;
+ u32 addr;
+ u16 impedance;
+ struct snd_soc_codec *codec = cs43130->codec;
+
+ switch (msk) {
+ case CS43130_HPLOAD_DC_INT:
+ case CS43130_HPLOAD_AC_INT:
+ break;
+ default:
+ return 0;
+ }
+
+ regmap_read(cs43130->regmap, CS43130_HP_LOAD_1, &reg);
+ if (reg & CS43130_HPLOAD_CHN_SEL)
+ left_ch = false;
+
+ if (msk == CS43130_HPLOAD_DC_INT)
+ addr = CS43130_HP_DC_STAT_1;
+ else
+ addr = CS43130_HP_AC_STAT_1;
+
+ regmap_read(cs43130->regmap, addr, &reg);
+ impedance = reg >> 3;
+ regmap_read(cs43130->regmap, addr + 1, &reg);
+ impedance |= reg << 5;
+
+ if (msk == CS43130_HPLOAD_DC_INT) {
+ if (left_ch)
+ cs43130->hpload_dc[HP_LEFT] = impedance;
+ else
+ cs43130->hpload_dc[HP_RIGHT] = impedance;
+
+ dev_dbg(codec->dev, "HP DC impedance (Ch %u): %u\n", !left_ch,
+ impedance);
+ } else {
+ if (left_ch)
+ cs43130->hpload_ac[ac_idx][HP_LEFT] = impedance;
+ else
+ cs43130->hpload_ac[ac_idx][HP_RIGHT] = impedance;
+
+ dev_dbg(codec->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n",
+ cs43130->ac_freq[ac_idx], !left_ch, impedance);
+ }
+
+ return 0;
+}
+
+static int cs43130_hpload_proc(struct cs43130_private *cs43130,
+ struct reg_sequence *seq, int seq_size,
+ unsigned int rslt_msk, int ac_idx)
+{
+ int ret;
+ unsigned int msk;
+ u16 ac_reg_val;
+ struct snd_soc_codec *codec = cs43130->codec;
+
+ reinit_completion(&cs43130->hpload_evt);
+
+ if (rslt_msk == CS43130_HPLOAD_AC_INT) {
+ ac_reg_val = cs43130_get_ac_reg_val(cs43130->ac_freq[ac_idx]);
+ regmap_update_bits(cs43130->regmap, CS43130_HP_LOAD_1,
+ CS43130_HPLOAD_AC_START, 0);
+ regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_1,
+ CS43130_HP_MEAS_LOAD_MASK,
+ ac_reg_val >> CS43130_HP_MEAS_LOAD_1_SHIFT);
+ regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_2,
+ CS43130_HP_MEAS_LOAD_MASK,
+ ac_reg_val >> CS43130_HP_MEAS_LOAD_2_SHIFT);
+ }
+
+ regmap_multi_reg_write(cs43130->regmap, seq,
+ seq_size);
+
+ ret = wait_for_completion_timeout(&cs43130->hpload_evt,
+ msecs_to_jiffies(1000));
+ regmap_read(cs43130->regmap, CS43130_INT_MASK_4, &msk);
+ if (!ret) {
+ dev_err(codec->dev, "Timeout waiting for HPLOAD interrupt\n");
+ return -1;
+ }
+
+ dev_dbg(codec->dev, "HP load stat: %x, INT_MASK_4: %x\n",
+ cs43130->hpload_stat, msk);
+ if ((cs43130->hpload_stat & (CS43130_HPLOAD_NO_DC_INT |
+ CS43130_HPLOAD_UNPLUG_INT |
+ CS43130_HPLOAD_OOR_INT)) ||
+ !(cs43130->hpload_stat & rslt_msk)) {
+ dev_dbg(codec->dev, "HP load measure failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static const struct reg_sequence hv_seq[][2] = {
+ {
+ {CS43130_CLASS_H_CTL, 0x1C},
+ {CS43130_HP_OUT_CTL_1, 0x10},
+ },
+ {
+ {CS43130_CLASS_H_CTL, 0x1E},
+ {CS43130_HP_OUT_CTL_1, 0x20},
+ },
+ {
+ {CS43130_CLASS_H_CTL, 0x1E},
+ {CS43130_HP_OUT_CTL_1, 0x30},
+ },
+};
+
+static int cs43130_set_hv(struct regmap *regmap, u16 hpload_dc,
+ const u16 *dc_threshold)
+{
+ int i;
+
+ for (i = 0; i < CS43130_DC_THRESHOLD; i++) {
+ if (hpload_dc <= dc_threshold[i])
+ break;
+ }
+
+ regmap_multi_reg_write(regmap, hv_seq[i], ARRAY_SIZE(hv_seq[i]));
+
+ return 0;
+}
+
+static void cs43130_imp_meas(struct work_struct *wk)
+{
+ unsigned int reg, seq_size;
+ int i, ret, ac_idx;
+ struct cs43130_private *cs43130;
+ struct snd_soc_codec *codec;
+ struct reg_sequences *hpload_seq;
+
+ cs43130 = container_of(wk, struct cs43130_private, work);
+ codec = cs43130->codec;
+
+ if (!cs43130->mclk)
+ return;
+
+ cs43130->hpload_done = false;
+
+ mutex_lock(&cs43130->clk_mutex);
+ if (!cs43130->clk_req) {
+ /* clk not in use */
+ cs43130_set_pll(codec, 0, 0, cs43130->mclk, CS43130_MCLK_22M);
+ if (cs43130->pll_bypass)
+ cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT);
+ else
+ cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL);
+ }
+
+ cs43130->clk_req++;
+ mutex_unlock(&cs43130->clk_mutex);
+
+ regmap_read(cs43130->regmap, CS43130_INT_STATUS_4, &reg);
+
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ hpload_seq = hpload_seq1;
+ seq_size = ARRAY_SIZE(hpload_seq1);
+ break;
+ case CS43131_CHIP_ID:
+ hpload_seq = hpload_seq2;
+ seq_size = ARRAY_SIZE(hpload_seq2);
+ break;
+ default:
+ WARN(1, "Invalid dev_id for meas: %d", cs43130->dev_id);
+ return;
+ }
+
+ i = 0;
+ ac_idx = 0;
+ while (i < seq_size) {
+ ret = cs43130_hpload_proc(cs43130, hpload_seq[i].seq,
+ hpload_seq[i].size,
+ hpload_seq[i].msk, ac_idx);
+ if (ret < 0)
+ goto exit;
+
+ cs43130_update_hpload(hpload_seq[i].msk, ac_idx, cs43130);
+
+ if (cs43130->ac_meas &&
+ hpload_seq[i].msk == CS43130_HPLOAD_AC_INT &&
+ ac_idx < CS43130_AC_FREQ - 1) {
+ ac_idx++;
+ } else {
+ ac_idx = 0;
+ i++;
+ }
+ }
+ cs43130->hpload_done = true;
+
+ if (cs43130->hpload_dc[HP_LEFT] >= CS43130_LINEOUT_LOAD)
+ snd_soc_jack_report(&cs43130->jack, CS43130_JACK_LINEOUT,
+ CS43130_JACK_MASK);
+ else
+ snd_soc_jack_report(&cs43130->jack, CS43130_JACK_HEADPHONE,
+ CS43130_JACK_MASK);
+
+ dev_dbg(codec->dev, "Set HP output control. DC threshold\n");
+ for (i = 0; i < CS43130_DC_THRESHOLD; i++)
+ dev_dbg(codec->dev, "DC threshold[%d]: %u.\n", i,
+ cs43130->dc_threshold[i]);
+
+ cs43130_set_hv(cs43130->regmap, cs43130->hpload_dc[HP_LEFT],
+ cs43130->dc_threshold);
+
+exit:
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ cs43130_hpload_proc(cs43130, hp_dis_cal_seq,
+ ARRAY_SIZE(hp_dis_cal_seq),
+ CS43130_HPLOAD_OFF_INT, ac_idx);
+ break;
+ case CS43131_CHIP_ID:
+ cs43130_hpload_proc(cs43130, hp_dis_cal_seq2,
+ ARRAY_SIZE(hp_dis_cal_seq2),
+ CS43130_HPLOAD_OFF_INT, ac_idx);
+ }
+
+ regmap_multi_reg_write(cs43130->regmap, hp_cln_seq,
+ ARRAY_SIZE(hp_cln_seq));
+
+ mutex_lock(&cs43130->clk_mutex);
+ cs43130->clk_req--;
+ /* clk not in use */
+ if (!cs43130->clk_req)
+ cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO);
+ mutex_unlock(&cs43130->clk_mutex);
+}
+
+static irqreturn_t cs43130_irq_thread(int irq, void *data)
+{
+ struct cs43130_private *cs43130 = (struct cs43130_private *)data;
+ struct snd_soc_codec *codec = cs43130->codec;
+ unsigned int stickies[CS43130_NUM_INT];
+ unsigned int irq_occurrence = 0;
+ unsigned int masks[CS43130_NUM_INT];
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(stickies); i++) {
+ regmap_read(cs43130->regmap, CS43130_INT_STATUS_1 + i,
+ &stickies[i]);
+ regmap_read(cs43130->regmap, CS43130_INT_MASK_1 + i,
+ &masks[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(stickies); i++) {
+ stickies[i] = stickies[i] & (~masks[i]);
+ for (j = 0; j < 8; j++)
+ irq_occurrence += (stickies[i] >> j) & 1;
+ }
+ dev_dbg(codec->dev, "number of interrupts occurred (%u)\n",
+ irq_occurrence);
+
+ if (!irq_occurrence)
+ return IRQ_NONE;
+
+ if (stickies[0] & CS43130_XTAL_RDY_INT) {
+ complete(&cs43130->xtal_rdy);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[0] & CS43130_PLL_RDY_INT) {
+ complete(&cs43130->pll_rdy);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[3] & CS43130_HPLOAD_NO_DC_INT) {
+ cs43130->hpload_stat = stickies[3];
+ dev_err(codec->dev,
+ "DC load has not completed before AC load (%x)\n",
+ cs43130->hpload_stat);
+ complete(&cs43130->hpload_evt);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[3] & CS43130_HPLOAD_UNPLUG_INT) {
+ cs43130->hpload_stat = stickies[3];
+ dev_err(codec->dev, "HP unplugged during measurement (%x)\n",
+ cs43130->hpload_stat);
+ complete(&cs43130->hpload_evt);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[3] & CS43130_HPLOAD_OOR_INT) {
+ cs43130->hpload_stat = stickies[3];
+ dev_err(codec->dev, "HP load out of range (%x)\n",
+ cs43130->hpload_stat);
+ complete(&cs43130->hpload_evt);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[3] & CS43130_HPLOAD_AC_INT) {
+ cs43130->hpload_stat = stickies[3];
+ dev_dbg(codec->dev, "HP AC load measurement done (%x)\n",
+ cs43130->hpload_stat);
+ complete(&cs43130->hpload_evt);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[3] & CS43130_HPLOAD_DC_INT) {
+ cs43130->hpload_stat = stickies[3];
+ dev_dbg(codec->dev, "HP DC load measurement done (%x)\n",
+ cs43130->hpload_stat);
+ complete(&cs43130->hpload_evt);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[3] & CS43130_HPLOAD_ON_INT) {
+ cs43130->hpload_stat = stickies[3];
+ dev_dbg(codec->dev, "HP load state machine on done (%x)\n",
+ cs43130->hpload_stat);
+ complete(&cs43130->hpload_evt);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[3] & CS43130_HPLOAD_OFF_INT) {
+ cs43130->hpload_stat = stickies[3];
+ dev_dbg(codec->dev, "HP load state machine off done (%x)\n",
+ cs43130->hpload_stat);
+ complete(&cs43130->hpload_evt);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[0] & CS43130_XTAL_ERR_INT) {
+ dev_err(codec->dev, "Crystal err: clock is not running\n");
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[0] & CS43130_HP_UNPLUG_INT) {
+ dev_dbg(codec->dev, "HP unplugged\n");
+ cs43130->hpload_done = false;
+ snd_soc_jack_report(&cs43130->jack, 0, CS43130_JACK_MASK);
+ return IRQ_HANDLED;
+ }
+
+ if (stickies[0] & CS43130_HP_PLUG_INT) {
+ if (cs43130->dc_meas && !cs43130->hpload_done &&
+ !work_busy(&cs43130->work)) {
+ dev_dbg(codec->dev, "HP load queue work\n");
+ queue_work(cs43130->wq, &cs43130->work);
+ }
+
+ snd_soc_jack_report(&cs43130->jack, SND_JACK_MECHANICAL,
+ CS43130_JACK_MASK);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int cs43130_probe(struct snd_soc_codec *codec)
+{
+ int ret;
+ struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_card *card = codec->component.card;
+ unsigned int reg;
+
+ cs43130->codec = codec;
+
+ if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) {
+ regmap_update_bits(cs43130->regmap, CS43130_CRYSTAL_SET,
+ CS43130_XTAL_IBIAS_MASK,
+ cs43130->xtal_ibias);
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_XTAL_ERR_INT, 0);
+ }
+
+ ret = snd_soc_card_jack_new(card, "Headphone", CS43130_JACK_MASK,
+ &cs43130->jack, NULL, 0);
+ if (ret < 0) {
+ dev_err(codec->dev, "Cannot create jack\n");
+ return ret;
+ }
+
+ cs43130->hpload_done = false;
+ if (cs43130->dc_meas) {
+ ret = device_create_file(codec->dev, &dev_attr_hpload_dc_l);
+ if (ret < 0)
+ return ret;
+
+ ret = device_create_file(codec->dev, &dev_attr_hpload_dc_r);
+ if (ret < 0)
+ return ret;
+
+ ret = device_create_file(codec->dev, &dev_attr_hpload_ac_l);
+ if (ret < 0)
+ return ret;
+
+ ret = device_create_file(codec->dev, &dev_attr_hpload_ac_r);
+ if (ret < 0)
+ return ret;
+
+ cs43130->wq = create_singlethread_workqueue("cs43130_hp");
+ INIT_WORK(&cs43130->work, cs43130_imp_meas);
+ }
+
+ regmap_read(cs43130->regmap, CS43130_INT_STATUS_1, &reg);
+ regmap_read(cs43130->regmap, CS43130_HP_STATUS, &reg);
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT, 0);
+ regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT,
+ CS43130_HP_DETECT_CTRL_MASK, 0);
+ regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT,
+ CS43130_HP_DETECT_CTRL_MASK,
+ CS43130_HP_DETECT_CTRL_MASK);
+
+ return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_cs43130 = {
+ .probe = cs43130_probe,
+ .component_driver = {
+ .controls = cs43130_snd_controls,
+ .num_controls = ARRAY_SIZE(cs43130_snd_controls),
+ },
+ .set_sysclk = cs43130_codec_set_sysclk,
+ .set_pll = cs43130_set_pll,
+};
+
+static const struct regmap_config cs43130_regmap = {
+ .reg_bits = 24,
+ .pad_bits = 8,
+ .val_bits = 8,
+
+ .max_register = CS43130_LASTREG,
+ .reg_defaults = cs43130_reg_defaults,
+ .num_reg_defaults = ARRAY_SIZE(cs43130_reg_defaults),
+ .readable_reg = cs43130_readable_register,
+ .precious_reg = cs43130_precious_register,
+ .volatile_reg = cs43130_volatile_register,
+ .cache_type = REGCACHE_RBTREE,
+ .use_single_rw = true, /* needed for regcache_sync */
+};
+
+static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {
+ 50,
+ 120,
+};
+
+static int cs43130_handle_device_data(struct i2c_client *i2c_client,
+ struct cs43130_private *cs43130)
+{
+ struct device_node *np = i2c_client->dev.of_node;
+ unsigned int val;
+ int i;
+
+ if (of_property_read_u32(np, "cirrus,xtal-ibias", &val) < 0) {
+ /* Crystal is unused. System clock is used for external MCLK */
+ cs43130->xtal_ibias = CS43130_XTAL_UNUSED;
+ return 0;
+ }
+
+ switch (val) {
+ case 1:
+ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_7_5UA;
+ break;
+ case 2:
+ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_12_5UA;
+ break;
+ case 3:
+ cs43130->xtal_ibias = CS43130_XTAL_IBIAS_15UA;
+ break;
+ default:
+ dev_err(&i2c_client->dev,
+ "Invalid cirrus,xtal-ibias value: %d\n", val);
+ return -EINVAL;
+ }
+
+ cs43130->dc_meas = of_property_read_bool(np, "cirrus,dc-measure");
+ cs43130->ac_meas = of_property_read_bool(np, "cirrus,ac-measure");
+
+ if (of_property_read_u16_array(np, "cirrus,ac-freq", cs43130->ac_freq,
+ CS43130_AC_FREQ) < 0) {
+ for (i = 0; i < CS43130_AC_FREQ; i++)
+ cs43130->ac_freq[i] = cs43130_ac_freq[i];
+ }
+
+ if (of_property_read_u16_array(np, "cirrus,dc-threshold",
+ cs43130->dc_threshold,
+ CS43130_DC_THRESHOLD) < 0) {
+ for (i = 0; i < CS43130_DC_THRESHOLD; i++)
+ cs43130->dc_threshold[i] = cs43130_dc_threshold[i];
+ }
+
+ return 0;
+}
+
+static int cs43130_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct cs43130_private *cs43130;
+ int ret;
+ unsigned int devid = 0;
+ unsigned int reg;
+ int i;
+
+ cs43130 = devm_kzalloc(&client->dev, sizeof(*cs43130), GFP_KERNEL);
+ if (!cs43130)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, cs43130);
+
+ cs43130->regmap = devm_regmap_init_i2c(client, &cs43130_regmap);
+ if (IS_ERR(cs43130->regmap)) {
+ ret = PTR_ERR(cs43130->regmap);
+ return ret;
+ }
+
+ if (client->dev.of_node) {
+ ret = cs43130_handle_device_data(client, cs43130);
+ if (ret != 0)
+ return ret;
+ }
+ for (i = 0; i < ARRAY_SIZE(cs43130->supplies); i++)
+ cs43130->supplies[i].supply = cs43130_supply_names[i];
+
+ ret = devm_regulator_bulk_get(&client->dev,
+ ARRAY_SIZE(cs43130->supplies),
+ cs43130->supplies);
+ if (ret != 0) {
+ dev_err(&client->dev, "Failed to request supplies: %d\n", ret);
+ return ret;
+ }
+ ret = regulator_bulk_enable(ARRAY_SIZE(cs43130->supplies),
+ cs43130->supplies);
+ if (ret != 0) {
+ dev_err(&client->dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ cs43130->reset_gpio = devm_gpiod_get_optional(&client->dev,
+ "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(cs43130->reset_gpio))
+ return PTR_ERR(cs43130->reset_gpio);
+
+ gpiod_set_value_cansleep(cs43130->reset_gpio, 1);
+
+ usleep_range(2000, 2050);
+
+ ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, &reg);
+
+ devid = (reg & 0xFF) << 12;
+ ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, &reg);
+ devid |= (reg & 0xFF) << 4;
+ ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, &reg);
+ devid |= (reg & 0xF0) >> 4;
+
+ switch (devid) {
+ case CS43130_CHIP_ID:
+ case CS4399_CHIP_ID:
+ case CS43131_CHIP_ID:
+ case CS43198_CHIP_ID:
+ break;
+ default:
+ dev_err(&client->dev,
+ "CS43130 Device ID %X. Expected ID %X, %X, %X or %X\n",
+ devid, CS43130_CHIP_ID, CS4399_CHIP_ID,
+ CS43131_CHIP_ID, CS43198_CHIP_ID);
+ ret = -ENODEV;
+ goto err;
+ }
+
+ cs43130->dev_id = devid;
+ ret = regmap_read(cs43130->regmap, CS43130_REV_ID, &reg);
+ if (ret < 0) {
+ dev_err(&client->dev, "Get Revision ID failed\n");
+ goto err;
+ }
+
+ dev_info(&client->dev,
+ "Cirrus Logic CS43130 (%x), Revision: %02X\n", devid,
+ reg & 0xFF);
+
+ mutex_init(&cs43130->clk_mutex);
+
+ init_completion(&cs43130->xtal_rdy);
+ init_completion(&cs43130->pll_rdy);
+ init_completion(&cs43130->hpload_evt);
+
+ ret = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, cs43130_irq_thread,
+ IRQF_ONESHOT | IRQF_TRIGGER_LOW,
+ "cs43130", cs43130);
+ if (ret != 0) {
+ dev_err(&client->dev, "Failed to request IRQ: %d\n", ret);
+ return ret;
+ }
+
+ cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
+
+ pm_runtime_set_autosuspend_delay(&client->dev, 100);
+ pm_runtime_use_autosuspend(&client->dev);
+ pm_runtime_set_active(&client->dev);
+ pm_runtime_enable(&client->dev);
+
+ switch (cs43130->dev_id) {
+ case CS43130_CHIP_ID:
+ case CS43131_CHIP_ID:
+ memcpy(all_hp_widgets, digital_hp_widgets,
+ sizeof(digital_hp_widgets));
+ memcpy(all_hp_widgets + ARRAY_SIZE(digital_hp_widgets),
+ analog_hp_widgets, sizeof(analog_hp_widgets));
+ memcpy(all_hp_routes, digital_hp_routes,
+ sizeof(digital_hp_routes));
+ memcpy(all_hp_routes + ARRAY_SIZE(digital_hp_routes),
+ analog_hp_routes, sizeof(analog_hp_routes));
+
+ soc_codec_dev_cs43130.component_driver.dapm_widgets =
+ all_hp_widgets;
+ soc_codec_dev_cs43130.component_driver.num_dapm_widgets =
+ ARRAY_SIZE(all_hp_widgets);
+ soc_codec_dev_cs43130.component_driver.dapm_routes =
+ all_hp_routes;
+ soc_codec_dev_cs43130.component_driver.num_dapm_routes =
+ ARRAY_SIZE(all_hp_routes);
+ break;
+ case CS43198_CHIP_ID:
+ case CS4399_CHIP_ID:
+ soc_codec_dev_cs43130.component_driver.dapm_widgets =
+ digital_hp_widgets;
+ soc_codec_dev_cs43130.component_driver.num_dapm_widgets =
+ ARRAY_SIZE(digital_hp_widgets);
+ soc_codec_dev_cs43130.component_driver.dapm_routes =
+ digital_hp_routes;
+ soc_codec_dev_cs43130.component_driver.num_dapm_routes =
+ ARRAY_SIZE(digital_hp_routes);
+ }
+
+ ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_cs43130,
+ cs43130_dai, ARRAY_SIZE(cs43130_dai));
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "snd_soc_register_codec failed with ret = %d\n", ret);
+ goto err;
+ }
+
+ regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
+ CS43130_ASP_3ST_MASK, 0);
+ regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,
+ CS43130_XSP_3ST_MASK, 0);
+
+ return 0;
+err:
+ return ret;
+}
+
+static int cs43130_i2c_remove(struct i2c_client *client)
+{
+ struct cs43130_private *cs43130 = i2c_get_clientdata(client);
+
+ if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_XTAL_ERR_INT,
+ 1 << CS43130_XTAL_ERR_INT_SHIFT);
+
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT,
+ CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT);
+
+ if (cs43130->dc_meas) {
+ cancel_work_sync(&cs43130->work);
+ flush_workqueue(cs43130->wq);
+
+ device_remove_file(&client->dev, &dev_attr_hpload_dc_l);
+ device_remove_file(&client->dev, &dev_attr_hpload_dc_r);
+ device_remove_file(&client->dev, &dev_attr_hpload_ac_l);
+ device_remove_file(&client->dev, &dev_attr_hpload_ac_r);
+ }
+
+ if (cs43130->reset_gpio)
+ gpiod_set_value_cansleep(cs43130->reset_gpio, 0);
+
+ pm_runtime_disable(&client->dev);
+ regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
+
+ snd_soc_unregister_codec(&client->dev);
+
+ return 0;
+}
+
+static int __maybe_unused cs43130_runtime_suspend(struct device *dev)
+{
+ struct cs43130_private *cs43130 = dev_get_drvdata(dev);
+
+ if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_XTAL_ERR_INT,
+ 1 << CS43130_XTAL_ERR_INT_SHIFT);
+
+ regcache_cache_only(cs43130->regmap, true);
+ regcache_mark_dirty(cs43130->regmap);
+
+ gpiod_set_value_cansleep(cs43130->reset_gpio, 0);
+
+ regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
+
+ return 0;
+}
+
+static int __maybe_unused cs43130_runtime_resume(struct device *dev)
+{
+ struct cs43130_private *cs43130 = dev_get_drvdata(dev);
+ int ret;
+
+ ret = regulator_bulk_enable(CS43130_NUM_SUPPLIES, cs43130->supplies);
+ if (ret != 0) {
+ dev_err(dev, "Failed to enable supplies: %d\n", ret);
+ return ret;
+ }
+
+ regcache_cache_only(cs43130->regmap, false);
+
+ gpiod_set_value_cansleep(cs43130->reset_gpio, 1);
+
+ usleep_range(2000, 2050);
+
+ ret = regcache_sync(cs43130->regmap);
+ if (ret != 0) {
+ dev_err(dev, "Failed to restore register cache\n");
+ goto err;
+ }
+
+ if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)
+ regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,
+ CS43130_XTAL_ERR_INT, 0);
+
+ return 0;
+err:
+ regcache_cache_only(cs43130->regmap, true);
+ regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
+
+ return ret;
+}
+
+static const struct dev_pm_ops cs43130_runtime_pm = {
+ SET_RUNTIME_PM_OPS(cs43130_runtime_suspend, cs43130_runtime_resume,
+ NULL)
+};
+
+static const struct of_device_id cs43130_of_match[] = {
+ {.compatible = "cirrus,cs43130",},
+ {.compatible = "cirrus,cs4399",},
+ {.compatible = "cirrus,cs43131",},
+ {.compatible = "cirrus,cs43198",},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, cs43130_of_match);
+
+static const struct i2c_device_id cs43130_i2c_id[] = {
+ {"cs43130", 0},
+ {"cs4399", 0},
+ {"cs43131", 0},
+ {"cs43198", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, cs43130_i2c_id);
+
+static struct i2c_driver cs43130_i2c_driver = {
+ .driver = {
+ .name = "cs43130",
+ .of_match_table = cs43130_of_match,
+ .pm = &cs43130_runtime_pm,
+ },
+ .id_table = cs43130_i2c_id,
+ .probe = cs43130_i2c_probe,
+ .remove = cs43130_i2c_remove,
+};
+
+module_i2c_driver(cs43130_i2c_driver);
+
+MODULE_AUTHOR("Li Xu <li.xu@cirrus.com>");
+MODULE_DESCRIPTION("Cirrus Logic CS43130 ALSA SoC Codec Driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h
new file mode 100644
index 000000000000..781258418d89
--- /dev/null
+++ b/sound/soc/codecs/cs43130.h
@@ -0,0 +1,546 @@
+/*
+ * ALSA SoC CS43130 codec driver
+ *
+ * Copyright 2017 Cirrus Logic, Inc.
+ *
+ * Author: Li Xu <li.xu@cirrus.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#ifndef __CS43130_H__
+#define __CS43130_H__
+
+/* CS43130 registers addresses */
+/* all reg address is shifted by a byte for control byte to be LSB */
+#define CS43130_FIRSTREG 0x010000
+#define CS43130_LASTREG 0x190000
+#define CS43130_CHIP_ID 0x00043130
+#define CS4399_CHIP_ID 0x00043990
+#define CS43131_CHIP_ID 0x00043131
+#define CS43198_CHIP_ID 0x00043198
+#define CS43130_DEVID_AB 0x010000 /* Device ID A & B [RO] */
+#define CS43130_DEVID_CD 0x010001 /* Device ID C & D [RO] */
+#define CS43130_DEVID_E 0x010002 /* Device ID E [RO] */
+#define CS43130_FAB_ID 0x010003 /* Fab ID [RO] */
+#define CS43130_REV_ID 0x010004 /* Revision ID [RO] */
+#define CS43130_SUBREV_ID 0x010005 /* Subrevision ID */
+#define CS43130_SYS_CLK_CTL_1 0x010006 /* System Clocking Ctl 1 */
+#define CS43130_SP_SRATE 0x01000B /* Serial Port Sample Rate */
+#define CS43130_SP_BITSIZE 0x01000C /* Serial Port Bit Size */
+#define CS43130_PAD_INT_CFG 0x01000D /* Pad Interface Config */
+#define CS43130_DXD1 0x010010 /* DXD1 */
+#define CS43130_DXD7 0x010025 /* DXD7 */
+#define CS43130_DXD19 0x010026 /* DXD19 */
+#define CS43130_DXD17 0x010027 /* DXD17 */
+#define CS43130_DXD18 0x010028 /* DXD18 */
+#define CS43130_DXD12 0x01002C /* DXD12 */
+#define CS43130_DXD8 0x01002E /* DXD8 */
+#define CS43130_PWDN_CTL 0x020000 /* Power Down Ctl */
+#define CS43130_DXD2 0x020019 /* DXD2 */
+#define CS43130_CRYSTAL_SET 0x020052 /* Crystal Setting */
+#define CS43130_PLL_SET_1 0x030001 /* PLL Setting 1 */
+#define CS43130_PLL_SET_2 0x030002 /* PLL Setting 2 */
+#define CS43130_PLL_SET_3 0x030003 /* PLL Setting 3 */
+#define CS43130_PLL_SET_4 0x030004 /* PLL Setting 4 */
+#define CS43130_PLL_SET_5 0x030005 /* PLL Setting 5 */
+#define CS43130_PLL_SET_6 0x030008 /* PLL Setting 6 */
+#define CS43130_PLL_SET_7 0x03000A /* PLL Setting 7 */
+#define CS43130_PLL_SET_8 0x03001B /* PLL Setting 8 */
+#define CS43130_PLL_SET_9 0x040002 /* PLL Setting 9 */
+#define CS43130_PLL_SET_10 0x040003 /* PLL Setting 10 */
+#define CS43130_CLKOUT_CTL 0x040004 /* CLKOUT Ctl */
+#define CS43130_ASP_NUM_1 0x040010 /* ASP Numerator 1 */
+#define CS43130_ASP_NUM_2 0x040011 /* ASP Numerator 2 */
+#define CS43130_ASP_DEN_1 0x040012 /* ASP Denominator 1 */
+#define CS43130_ASP_DEN_2 0x040013 /* ASP Denominator 2 */
+#define CS43130_ASP_LRCK_HI_TIME_1 0x040014 /* ASP LRCK High Time 1 */
+#define CS43130_ASP_LRCK_HI_TIME_2 0x040015 /* ASP LRCK High Time 2 */
+#define CS43130_ASP_LRCK_PERIOD_1 0x040016 /* ASP LRCK Period 1 */
+#define CS43130_ASP_LRCK_PERIOD_2 0x040017 /* ASP LRCK Period 2 */
+#define CS43130_ASP_CLOCK_CONF 0x040018 /* ASP Clock Config */
+#define CS43130_ASP_FRAME_CONF 0x040019 /* ASP Frame Config */
+#define CS43130_XSP_NUM_1 0x040020 /* XSP Numerator 1 */
+#define CS43130_XSP_NUM_2 0x040021 /* XSP Numerator 2 */
+#define CS43130_XSP_DEN_1 0x040022 /* XSP Denominator 1 */
+#define CS43130_XSP_DEN_2 0x040023 /* XSP Denominator 2 */
+#define CS43130_XSP_LRCK_HI_TIME_1 0x040024 /* XSP LRCK High Time 1 */
+#define CS43130_XSP_LRCK_HI_TIME_2 0x040025 /* XSP LRCK High Time 2 */
+#define CS43130_XSP_LRCK_PERIOD_1 0x040026 /* XSP LRCK Period 1 */
+#define CS43130_XSP_LRCK_PERIOD_2 0x040027 /* XSP LRCK Period 2 */
+#define CS43130_XSP_CLOCK_CONF 0x040028 /* XSP Clock Config */
+#define CS43130_XSP_FRAME_CONF 0x040029 /* XSP Frame Config */
+#define CS43130_ASP_CH_1_LOC 0x050000 /* ASP Chan 1 Location */
+#define CS43130_ASP_CH_2_LOC 0x050001 /* ASP Chan 2 Location */
+#define CS43130_ASP_CH_1_SZ_EN 0x05000A /* ASP Chan 1 Size, Enable */
+#define CS43130_ASP_CH_2_SZ_EN 0x05000B /* ASP Chan 2 Size, Enable */
+#define CS43130_XSP_CH_1_LOC 0x060000 /* XSP Chan 1 Location */
+#define CS43130_XSP_CH_2_LOC 0x060001 /* XSP Chan 2 Location */
+#define CS43130_XSP_CH_1_SZ_EN 0x06000A /* XSP Chan 1 Size, Enable */
+#define CS43130_XSP_CH_2_SZ_EN 0x06000B /* XSP Chan 2 Size, Enable */
+#define CS43130_DSD_VOL_B 0x070000 /* DSD Volume B */
+#define CS43130_DSD_VOL_A 0x070001 /* DSD Volume A */
+#define CS43130_DSD_PATH_CTL_1 0x070002 /* DSD Proc Path Sig Ctl 1 */
+#define CS43130_DSD_INT_CFG 0x070003 /* DSD Interface Config */
+#define CS43130_DSD_PATH_CTL_2 0x070004 /* DSD Proc Path Sig Ctl 2 */
+#define CS43130_DSD_PCM_MIX_CTL 0x070005 /* DSD and PCM Mixing Ctl */
+#define CS43130_DSD_PATH_CTL_3 0x070006 /* DSD Proc Path Sig Ctl 3 */
+#define CS43130_HP_OUT_CTL_1 0x080000 /* HP Output Ctl 1 */
+#define CS43130_DXD16 0x080024 /* DXD16 */
+#define CS43130_DXD13 0x080032 /* DXD13 */
+#define CS43130_PCM_FILT_OPT 0x090000 /* PCM Filter Option */
+#define CS43130_PCM_VOL_B 0x090001 /* PCM Volume B */
+#define CS43130_PCM_VOL_A 0x090002 /* PCM Volume A */
+#define CS43130_PCM_PATH_CTL_1 0x090003 /* PCM Path Signal Ctl 1 */
+#define CS43130_PCM_PATH_CTL_2 0x090004 /* PCM Path Signal Ctl 2 */
+#define CS43130_DXD6 0x090097 /* DXD6 */
+#define CS43130_CLASS_H_CTL 0x0B0000 /* Class H Ctl */
+#define CS43130_DXD15 0x0B0005 /* DXD15 */
+#define CS43130_DXD14 0x0B0006 /* DXD14 */
+#define CS43130_DXD3 0x0C0002 /* DXD3 */
+#define CS43130_DXD10 0x0C0003 /* DXD10 */
+#define CS43130_DXD11 0x0C0005 /* DXD11 */
+#define CS43130_DXD9 0x0C0006 /* DXD9 */
+#define CS43130_DXD4 0x0C0009 /* DXD4 */
+#define CS43130_DXD5 0x0C000E /* DXD5 */
+#define CS43130_HP_DETECT 0x0D0000 /* HP Detect */
+#define CS43130_HP_STATUS 0x0D0001 /* HP Status [RO] */
+#define CS43130_HP_LOAD_1 0x0E0000 /* HP Load 1 */
+#define CS43130_HP_MEAS_LOAD_1 0x0E0003 /* HP Load Measurement 1 */
+#define CS43130_HP_MEAS_LOAD_2 0x0E0004 /* HP Load Measurement 2 */
+#define CS43130_HP_DC_STAT_1 0x0E000D /* HP DC Load Status 0 [RO] */
+#define CS43130_HP_DC_STAT_2 0x0E000E /* HP DC Load Status 1 [RO] */
+#define CS43130_HP_AC_STAT_1 0x0E0010 /* HP AC Load Status 0 [RO] */
+#define CS43130_HP_AC_STAT_2 0x0E0011 /* HP AC Load Status 1 [RO] */
+#define CS43130_HP_LOAD_STAT 0x0E001A /* HP Load Status [RO] */
+#define CS43130_INT_STATUS_1 0x0F0000 /* Interrupt Status 1 */
+#define CS43130_INT_STATUS_2 0x0F0001 /* Interrupt Status 2 */
+#define CS43130_INT_STATUS_3 0x0F0002 /* Interrupt Status 3 */
+#define CS43130_INT_STATUS_4 0x0F0003 /* Interrupt Status 4 */
+#define CS43130_INT_STATUS_5 0x0F0004 /* Interrupt Status 5 */
+#define CS43130_INT_MASK_1 0x0F0010 /* Interrupt Mask 1 */
+#define CS43130_INT_MASK_2 0x0F0011 /* Interrupt Mask 2 */
+#define CS43130_INT_MASK_3 0x0F0012 /* Interrupt Mask 3 */
+#define CS43130_INT_MASK_4 0x0F0013 /* Interrupt Mask 4 */
+#define CS43130_INT_MASK_5 0x0F0014 /* Interrupt Mask 5 */
+
+#define CS43130_MCLK_SRC_SEL_MASK 0x03
+#define CS43130_MCLK_SRC_SEL_SHIFT 0
+#define CS43130_MCLK_INT_MASK 0x04
+#define CS43130_MCLK_INT_SHIFT 2
+#define CS43130_CH_BITSIZE_MASK 0x03
+#define CS43130_CH_EN_MASK 0x04
+#define CS43130_CH_EN_SHIFT 2
+#define CS43130_ASP_BITSIZE_MASK 0x03
+#define CS43130_XSP_BITSIZE_MASK 0x0C
+#define CS43130_XSP_BITSIZE_SHIFT 2
+#define CS43130_SP_BITSIZE_ASP_SHIFT 0
+#define CS43130_HP_DETECT_CTRL_SHIFT 6
+#define CS43130_HP_DETECT_CTRL_MASK (0x03 << CS43130_HP_DETECT_CTRL_SHIFT)
+#define CS43130_HP_DETECT_INV_SHIFT 5
+#define CS43130_HP_DETECT_INV_MASK (1 << CS43130_HP_DETECT_INV_SHIFT)
+
+/* CS43130_INT_MASK_1 */
+#define CS43130_HP_PLUG_INT_SHIFT 6
+#define CS43130_HP_PLUG_INT (1 << CS43130_HP_PLUG_INT_SHIFT)
+#define CS43130_HP_UNPLUG_INT_SHIFT 5
+#define CS43130_HP_UNPLUG_INT (1 << CS43130_HP_UNPLUG_INT_SHIFT)
+#define CS43130_XTAL_RDY_INT_SHIFT 4
+#define CS43130_XTAL_RDY_INT_MASK 0x10
+#define CS43130_XTAL_RDY_INT (1 << CS43130_XTAL_RDY_INT_SHIFT)
+#define CS43130_XTAL_ERR_INT_SHIFT 3
+#define CS43130_XTAL_ERR_INT (1 << CS43130_XTAL_ERR_INT_SHIFT)
+#define CS43130_PLL_RDY_INT_MASK 0x04
+#define CS43130_PLL_RDY_INT_SHIFT 2
+#define CS43130_PLL_RDY_INT (1 << CS43130_PLL_RDY_INT_SHIFT)
+
+/* CS43130_INT_MASK_4 */
+#define CS43130_INT_MASK_ALL 0xFF
+#define CS43130_HPLOAD_NO_DC_INT_SHIFT 7
+#define CS43130_HPLOAD_NO_DC_INT (1 << CS43130_HPLOAD_NO_DC_INT_SHIFT)
+#define CS43130_HPLOAD_UNPLUG_INT_SHIFT 6
+#define CS43130_HPLOAD_UNPLUG_INT (1 << CS43130_HPLOAD_UNPLUG_INT_SHIFT)
+#define CS43130_HPLOAD_OOR_INT_SHIFT 4
+#define CS43130_HPLOAD_OOR_INT (1 << CS43130_HPLOAD_OOR_INT_SHIFT)
+#define CS43130_HPLOAD_AC_INT_SHIFT 3
+#define CS43130_HPLOAD_AC_INT (1 << CS43130_HPLOAD_AC_INT_SHIFT)
+#define CS43130_HPLOAD_DC_INT_SHIFT 2
+#define CS43130_HPLOAD_DC_INT (1 << CS43130_HPLOAD_DC_INT_SHIFT)
+#define CS43130_HPLOAD_OFF_INT_SHIFT 1
+#define CS43130_HPLOAD_OFF_INT (1 << CS43130_HPLOAD_OFF_INT_SHIFT)
+#define CS43130_HPLOAD_ON_INT 1
+
+/* CS43130_HP_LOAD_1 */
+#define CS43130_HPLOAD_EN_SHIFT 7
+#define CS43130_HPLOAD_EN (1 << CS43130_HPLOAD_EN_SHIFT)
+#define CS43130_HPLOAD_CHN_SEL_SHIFT 4
+#define CS43130_HPLOAD_CHN_SEL (1 << CS43130_HPLOAD_CHN_SEL_SHIFT)
+#define CS43130_HPLOAD_AC_START_SHIFT 1
+#define CS43130_HPLOAD_AC_START (1 << CS43130_HPLOAD_AC_START_SHIFT)
+#define CS43130_HPLOAD_DC_START 1
+
+/* Reg CS43130_SP_BITSIZE */
+#define CS43130_SP_BIT_SIZE_8 0x03
+#define CS43130_SP_BIT_SIZE_16 0x02
+#define CS43130_SP_BIT_SIZE_24 0x01
+#define CS43130_SP_BIT_SIZE_32 0x00
+
+/* Reg CS43130_SP_CH_SZ_EN */
+#define CS43130_CH_BIT_SIZE_8 0x00
+#define CS43130_CH_BIT_SIZE_16 0x01
+#define CS43130_CH_BIT_SIZE_24 0x02
+#define CS43130_CH_BIT_SIZE_32 0x03
+
+/* PLL */
+#define CS43130_PLL_START_MASK 0x01
+#define CS43130_PLL_MODE_MASK 0x02
+#define CS43130_PLL_MODE_SHIFT 1
+
+#define CS43130_PLL_REF_PREDIV_MASK 0x3
+
+#define CS43130_SP_STP_MASK 0x10
+#define CS43130_SP_STP_SHIFT 4
+#define CS43130_SP_5050_MASK 0x08
+#define CS43130_SP_5050_SHIFT 3
+#define CS43130_SP_FSD_MASK 0x07
+
+#define CS43130_SP_MODE_MASK 0x10
+#define CS43130_SP_MODE_SHIFT 4
+#define CS43130_SP_SCPOL_OUT_MASK 0x08
+#define CS43130_SP_SCPOL_OUT_SHIFT 3
+#define CS43130_SP_SCPOL_IN_MASK 0x04
+#define CS43130_SP_SCPOL_IN_SHIFT 2
+#define CS43130_SP_LCPOL_OUT_MASK 0x02
+#define CS43130_SP_LCPOL_OUT_SHIFT 1
+#define CS43130_SP_LCPOL_IN_MASK 0x01
+#define CS43130_SP_LCPOL_IN_SHIFT 0
+
+/* Reg CS43130_PWDN_CTL */
+#define CS43130_PDN_XSP_MASK 0x80
+#define CS43130_PDN_XSP_SHIFT 7
+#define CS43130_PDN_ASP_MASK 0x40
+#define CS43130_PDN_ASP_SHIFT 6
+#define CS43130_PDN_DSPIF_MASK 0x20
+#define CS43130_PDN_DSDIF_SHIFT 5
+#define CS43130_PDN_HP_MASK 0x10
+#define CS43130_PDN_HP_SHIFT 4
+#define CS43130_PDN_XTAL_MASK 0x08
+#define CS43130_PDN_XTAL_SHIFT 3
+#define CS43130_PDN_PLL_MASK 0x04
+#define CS43130_PDN_PLL_SHIFT 2
+#define CS43130_PDN_CLKOUT_MASK 0x02
+#define CS43130_PDN_CLKOUT_SHIFT 1
+
+/* Reg CS43130_HP_OUT_CTL_1 */
+#define CS43130_HP_IN_EN_SHIFT 3
+#define CS43130_HP_IN_EN_MASK 0x08
+
+/* Reg CS43130_PAD_INT_CFG */
+#define CS43130_ASP_3ST_MASK 0x01
+#define CS43130_XSP_3ST_MASK 0x02
+
+/* Reg CS43130_PLL_SET_2 */
+#define CS43130_PLL_DIV_DATA_MASK 0x000000FF
+#define CS43130_PLL_DIV_FRAC_0_DATA_SHIFT 0
+
+/* Reg CS43130_PLL_SET_3 */
+#define CS43130_PLL_DIV_FRAC_1_DATA_SHIFT 8
+
+/* Reg CS43130_PLL_SET_4 */
+#define CS43130_PLL_DIV_FRAC_2_DATA_SHIFT 16
+
+/* Reg CS43130_SP_DEN_1 */
+#define CS43130_SP_M_LSB_DATA_MASK 0x00FF
+#define CS43130_SP_M_LSB_DATA_SHIFT 0
+
+/* Reg CS43130_SP_DEN_2 */
+#define CS43130_SP_M_MSB_DATA_MASK 0xFF00
+#define CS43130_SP_M_MSB_DATA_SHIFT 8
+
+/* Reg CS43130_SP_NUM_1 */
+#define CS43130_SP_N_LSB_DATA_MASK 0x00FF
+#define CS43130_SP_N_LSB_DATA_SHIFT 0
+
+/* Reg CS43130_SP_NUM_2 */
+#define CS43130_SP_N_MSB_DATA_MASK 0xFF00
+#define CS43130_SP_N_MSB_DATA_SHIFT 8
+
+/* Reg CS43130_SP_LRCK_HI_TIME_1 */
+#define CS43130_SP_LCHI_DATA_MASK 0x00FF
+#define CS43130_SP_LCHI_LSB_DATA_SHIFT 0
+
+/* Reg CS43130_SP_LRCK_HI_TIME_2 */
+#define CS43130_SP_LCHI_MSB_DATA_SHIFT 8
+
+/* Reg CS43130_SP_LRCK_PERIOD_1 */
+#define CS43130_SP_LCPR_DATA_MASK 0x00FF
+#define CS43130_SP_LCPR_LSB_DATA_SHIFT 0
+
+/* Reg CS43130_SP_LRCK_PERIOD_2 */
+#define CS43130_SP_LCPR_MSB_DATA_SHIFT 8
+
+#define CS43130_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
+ SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+#define CS43130_DOP_FORMATS (SNDRV_PCM_FMTBIT_DSD_U16_LE | \
+ SNDRV_PCM_FMTBIT_DSD_U16_BE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+/* Reg CS43130_CRYSTAL_SET */
+#define CS43130_XTAL_IBIAS_MASK 0x07
+
+/* Reg CS43130_PATH_CTL_1 */
+#define CS43130_MUTE_MASK 0x03
+#define CS43130_MUTE_EN 0x03
+
+/* Reg CS43130_DSD_INT_CFG */
+#define CS43130_DSD_MASTER 0x04
+
+/* Reg CS43130_DSD_PATH_CTL_2 */
+#define CS43130_DSD_SRC_MASK 0x60
+#define CS43130_DSD_SRC_SHIFT 5
+#define CS43130_DSD_EN_SHIFT 4
+#define CS43130_DSD_SPEED_MASK 0x04
+#define CS43130_DSD_SPEED_SHIFT 2
+
+/* Reg CS43130_DSD_PCM_MIX_CTL */
+#define CS43130_MIX_PCM_PREP_SHIFT 1
+#define CS43130_MIX_PCM_PREP_MASK 0x02
+
+#define CS43130_MIX_PCM_DSD_SHIFT 0
+#define CS43130_MIX_PCM_DSD_MASK 0x01
+
+/* Reg CS43130_HP_MEAS_LOAD */
+#define CS43130_HP_MEAS_LOAD_MASK 0x000000FF
+#define CS43130_HP_MEAS_LOAD_1_SHIFT 0
+#define CS43130_HP_MEAS_LOAD_2_SHIFT 8
+
+#define CS43130_MCLK_22M 22579200
+#define CS43130_MCLK_24M 24576000
+
+#define CS43130_LINEOUT_LOAD 5000
+#define CS43130_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT)
+#define CS43130_JACK_HEADPHONE (SND_JACK_MECHANICAL | \
+ SND_JACK_HEADPHONE)
+#define CS43130_JACK_MASK (SND_JACK_MECHANICAL | \
+ SND_JACK_LINEOUT | \
+ SND_JACK_HEADPHONE)
+
+enum cs43130_dsd_src {
+ CS43130_DSD_SRC_DSD = 0,
+ CS43130_DSD_SRC_ASP = 2,
+ CS43130_DSD_SRC_XSP = 3,
+};
+
+enum cs43130_asp_rate {
+ CS43130_ASP_SPRATE_32K = 0,
+ CS43130_ASP_SPRATE_44_1K,
+ CS43130_ASP_SPRATE_48K,
+ CS43130_ASP_SPRATE_88_2K,
+ CS43130_ASP_SPRATE_96K,
+ CS43130_ASP_SPRATE_176_4K,
+ CS43130_ASP_SPRATE_192K,
+ CS43130_ASP_SPRATE_352_8K,
+ CS43130_ASP_SPRATE_384K,
+};
+
+enum cs43130_mclk_src_sel {
+ CS43130_MCLK_SRC_EXT = 0,
+ CS43130_MCLK_SRC_PLL,
+ CS43130_MCLK_SRC_RCO
+};
+
+enum cs43130_mclk_int_freq {
+ CS43130_MCLK_24P5 = 0,
+ CS43130_MCLK_22P5,
+};
+
+enum cs43130_xtal_ibias {
+ CS43130_XTAL_UNUSED = -1,
+ CS43130_XTAL_IBIAS_15UA = 2,
+ CS43130_XTAL_IBIAS_12_5UA = 4,
+ CS43130_XTAL_IBIAS_7_5UA = 6,
+};
+
+enum cs43130_dai_id {
+ CS43130_ASP_PCM_DAI = 0,
+ CS43130_ASP_DOP_DAI,
+ CS43130_XSP_DOP_DAI,
+ CS43130_XSP_DSD_DAI,
+ CS43130_DAI_ID_MAX,
+};
+
+struct cs43130_clk_gen {
+ unsigned int mclk_int;
+ int fs;
+ u16 den;
+ u16 num;
+};
+
+/* frm_size = 16 */
+static const struct cs43130_clk_gen cs43130_16_clk_gen[] = {
+ {22579200, 32000, 441, 10,},
+ {22579200, 44100, 32, 1,},
+ {22579200, 48000, 147, 5,},
+ {22579200, 88200, 16, 1,},
+ {22579200, 96000, 147, 10,},
+ {22579200, 176400, 8, 1,},
+ {22579200, 192000, 147, 20,},
+ {22579200, 352800, 4, 1,},
+ {22579200, 384000, 147, 40,},
+ {24576000, 32000, 48, 1,},
+ {24576000, 44100, 5120, 147,},
+ {24576000, 48000, 32, 1,},
+ {24576000, 88200, 2560, 147,},
+ {24576000, 96000, 16, 1,},
+ {24576000, 176400, 1280, 147,},
+ {24576000, 192000, 8, 1,},
+ {24576000, 352800, 640, 147,},
+ {24576000, 384000, 4, 1,},
+};
+
+/* frm_size = 32 */
+static const struct cs43130_clk_gen cs43130_32_clk_gen[] = {
+ {22579200, 32000, 441, 20,},
+ {22579200, 44100, 16, 1,},
+ {22579200, 48000, 147, 10,},
+ {22579200, 88200, 8, 1,},
+ {22579200, 96000, 147, 20,},
+ {22579200, 176400, 4, 1,},
+ {22579200, 192000, 147, 40,},
+ {22579200, 352800, 2, 1,},
+ {22579200, 384000, 147, 80,},
+ {24576000, 32000, 24, 1,},
+ {24576000, 44100, 2560, 147,},
+ {24576000, 48000, 16, 1,},
+ {24576000, 88200, 1280, 147,},
+ {24576000, 96000, 8, 1,},
+ {24576000, 176400, 640, 147,},
+ {24576000, 192000, 4, 1,},
+ {24576000, 352800, 320, 147,},
+ {24576000, 384000, 2, 1,},
+};
+
+/* frm_size = 48 */
+static const struct cs43130_clk_gen cs43130_48_clk_gen[] = {
+ {22579200, 32000, 147, 100,},
+ {22579200, 44100, 32, 3,},
+ {22579200, 48000, 49, 5,},
+ {22579200, 88200, 16, 3,},
+ {22579200, 96000, 49, 10,},
+ {22579200, 176400, 8, 3,},
+ {22579200, 192000, 49, 20,},
+ {22579200, 352800, 4, 3,},
+ {22579200, 384000, 49, 40,},
+ {24576000, 32000, 16, 1,},
+ {24576000, 44100, 5120, 441,},
+ {24576000, 48000, 32, 3,},
+ {24576000, 88200, 2560, 441,},
+ {24576000, 96000, 16, 3,},
+ {24576000, 176400, 1280, 441,},
+ {24576000, 192000, 8, 3,},
+ {24576000, 352800, 640, 441,},
+ {24576000, 384000, 4, 3,},
+};
+
+/* frm_size = 64 */
+static const struct cs43130_clk_gen cs43130_64_clk_gen[] = {
+ {22579200, 32000, 441, 40,},
+ {22579200, 44100, 8, 1,},
+ {22579200, 48000, 147, 20,},
+ {22579200, 88200, 4, 1,},
+ {22579200, 96000, 147, 40,},
+ {22579200, 176400, 2, 1,},
+ {22579200, 192000, 147, 80,},
+ {22579200, 352800, 1, 1,},
+ {24576000, 32000, 12, 1,},
+ {24576000, 44100, 1280, 147,},
+ {24576000, 48000, 8, 1,},
+ {24576000, 88200, 640, 147,},
+ {24576000, 96000, 4, 1,},
+ {24576000, 176400, 320, 147,},
+ {24576000, 192000, 2, 1,},
+ {24576000, 352800, 160, 147,},
+ {24576000, 384000, 1, 1,},
+};
+
+struct cs43130_bitwidth_map {
+ unsigned int bitwidth;
+ u8 sp_bit;
+ u8 ch_bit;
+};
+
+struct cs43130_rate_map {
+ int fs;
+ int val;
+};
+
+#define HP_LEFT 0
+#define HP_RIGHT 1
+#define CS43130_AC_FREQ 10
+#define CS43130_DC_THRESHOLD 2
+
+#define CS43130_NUM_SUPPLIES 5
+static const char *const cs43130_supply_names[CS43130_NUM_SUPPLIES] = {
+ "VA",
+ "VP",
+ "VCP",
+ "VD",
+ "VL",
+};
+
+#define CS43130_NUM_INT 5 /* number of interrupt status reg */
+
+struct cs43130_dai {
+ unsigned int sclk;
+ unsigned int dai_format;
+ unsigned int dai_mode;
+};
+
+struct cs43130_private {
+ struct snd_soc_codec *codec;
+ struct regmap *regmap;
+ struct regulator_bulk_data supplies[CS43130_NUM_SUPPLIES];
+ struct gpio_desc *reset_gpio;
+ unsigned int dev_id; /* codec device ID */
+ int xtal_ibias;
+
+ /* shared by both DAIs */
+ struct mutex clk_mutex;
+ int clk_req;
+ bool pll_bypass;
+ struct completion xtal_rdy;
+ struct completion pll_rdy;
+ unsigned int mclk;
+ unsigned int mclk_int;
+ int mclk_int_src;
+
+ /* DAI specific */
+ struct cs43130_dai dais[CS43130_DAI_ID_MAX];
+
+ /* HP load specific */
+ bool dc_meas;
+ bool ac_meas;
+ bool hpload_done;
+ struct completion hpload_evt;
+ unsigned int hpload_stat;
+ u16 hpload_dc[2];
+ u16 dc_threshold[CS43130_DC_THRESHOLD];
+ u16 ac_freq[CS43130_AC_FREQ];
+ u16 hpload_ac[CS43130_AC_FREQ][2];
+ struct workqueue_struct *wq;
+ struct work_struct work;
+ struct snd_soc_jack jack;
+};
+
+#endif /* __CS43130_H__ */
diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c
index 231ca935cdf3..0a749c79ef57 100644
--- a/sound/soc/codecs/cs4349.c
+++ b/sound/soc/codecs/cs4349.c
@@ -255,7 +255,7 @@ static struct snd_soc_dai_driver cs4349_dai = {
.symmetric_rates = 1,
};
-static struct snd_soc_codec_driver soc_codec_dev_cs4349 = {
+static const struct snd_soc_codec_driver soc_codec_dev_cs4349 = {
.component_driver = {
.controls = cs4349_snd_controls,
.num_controls = ARRAY_SIZE(cs4349_snd_controls),
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index 47e6fddef92b..e09fc8f037f1 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -1183,7 +1183,7 @@ static struct regmap *cs47l24_get_regmap(struct device *dev)
return priv->core.arizona->regmap;
}
-static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
+static const struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
.probe = cs47l24_codec_probe,
.remove = cs47l24_codec_remove,
.get_regmap = cs47l24_get_regmap,
@@ -1203,7 +1203,7 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = {
},
};
-static struct snd_compr_ops cs47l24_compr_ops = {
+static const struct snd_compr_ops cs47l24_compr_ops = {
.open = cs47l24_open,
.free = wm_adsp_compr_free,
.set_params = wm_adsp_compr_set_params,
@@ -1213,7 +1213,7 @@ static struct snd_compr_ops cs47l24_compr_ops = {
.copy = wm_adsp_compr_copy,
};
-static struct snd_soc_platform_driver cs47l24_compr_platform = {
+static const struct snd_soc_platform_driver cs47l24_compr_platform = {
.compr_ops = &cs47l24_compr_ops,
};
diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c
index 06933a5d0a75..c7edf2df5e36 100644
--- a/sound/soc/codecs/cs53l30.c
+++ b/sound/soc/codecs/cs53l30.c
@@ -842,8 +842,7 @@ static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
{
struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec);
- if (priv->mute_gpio)
- gpiod_set_value_cansleep(priv->mute_gpio, mute);
+ gpiod_set_value_cansleep(priv->mute_gpio, mute);
return 0;
}
@@ -892,7 +891,7 @@ static int cs53l30_codec_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver cs53l30_driver = {
+static const struct snd_soc_codec_driver cs53l30_driver = {
.probe = cs53l30_codec_probe,
.set_bias_level = cs53l30_set_bias_level,
.idle_bias_off = true,
@@ -960,8 +959,7 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
goto error;
}
- if (cs53l30->reset_gpio)
- gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
+ gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
i2c_set_clientdata(client, cs53l30);
@@ -1056,8 +1054,7 @@ static int cs53l30_i2c_remove(struct i2c_client *client)
snd_soc_unregister_codec(&client->dev);
/* Hold down reset */
- if (cs53l30->reset_gpio)
- gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
+ gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
cs53l30->supplies);
@@ -1073,8 +1070,7 @@ static int cs53l30_runtime_suspend(struct device *dev)
regcache_cache_only(cs53l30->regmap, true);
/* Hold down reset */
- if (cs53l30->reset_gpio)
- gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
+ gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
cs53l30->supplies);
@@ -1094,8 +1090,7 @@ static int cs53l30_runtime_resume(struct device *dev)
return ret;
}
- if (cs53l30->reset_gpio)
- gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
+ gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
regcache_cache_only(cs53l30->regmap, false);
ret = regcache_sync(cs53l30->regmap);
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 2c12471e42a6..46b1fbb66eba 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -398,7 +398,7 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
static const u8 cx20442_reg;
-static struct snd_soc_codec_driver cx20442_codec_dev = {
+static const struct snd_soc_codec_driver cx20442_codec_dev = {
.probe = cx20442_codec_probe,
.remove = cx20442_codec_remove,
.set_bias_level = cx20442_set_bias_level,
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 17053dfc94cf..1af443ccbc51 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -1164,7 +1164,7 @@ static int da7210_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
+static const struct snd_soc_codec_driver soc_codec_dev_da7210 = {
.probe = da7210_probe,
.component_driver = {
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index c3e11897f8ae..cc0b2d2eaf15 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1787,7 +1787,7 @@ static int da7213_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_da7213 = {
+static const struct snd_soc_codec_driver soc_codec_dev_da7213 = {
.probe = da7213_probe,
.set_bias_level = da7213_set_bias_level,
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c
index 6e1940eb0653..b2d42ec1dcd9 100644
--- a/sound/soc/codecs/da7218.c
+++ b/sound/soc/codecs/da7218.c
@@ -3035,7 +3035,7 @@ static int da7218_resume(struct snd_soc_codec *codec)
#define da7218_resume NULL
#endif
-static struct snd_soc_codec_driver soc_codec_dev_da7218 = {
+static const struct snd_soc_codec_driver soc_codec_dev_da7218 = {
.probe = da7218_probe,
.remove = da7218_remove,
.suspend = da7218_suspend,
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index f71d72c22bfc..6f088536df32 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -1891,7 +1891,7 @@ static int da7219_resume(struct snd_soc_codec *codec)
#define da7219_resume NULL
#endif
-static struct snd_soc_codec_driver soc_codec_dev_da7219 = {
+static const struct snd_soc_codec_driver soc_codec_dev_da7219 = {
.probe = da7219_probe,
.remove = da7219_remove,
.suspend = da7219_suspend,
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index c1cc1c1c28f2..83db4d23c90b 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -1499,7 +1499,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_da732x = {
+static const struct snd_soc_codec_driver soc_codec_dev_da732x = {
.set_bias_level = da732x_set_bias_level,
.component_driver = {
.controls = da732x_snd_controls,
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
index 4efb5f897a0c..bd7faaee5802 100644
--- a/sound/soc/codecs/da9055.c
+++ b/sound/soc/codecs/da9055.c
@@ -1451,7 +1451,7 @@ static int da9055_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_da9055 = {
+static const struct snd_soc_codec_driver soc_codec_dev_da9055 = {
.probe = da9055_probe,
.set_bias_level = da9055_set_bias_level,
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index c82b9dc41e9a..b88a1ee66f80 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -19,6 +19,8 @@
*
*/
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
@@ -27,6 +29,34 @@
#include <sound/soc.h>
#include <sound/soc-dapm.h>
+static int dmic_daiops_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct gpio_desc *dmic_en = snd_soc_dai_get_drvdata(dai);
+
+ if (!dmic_en)
+ return 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ gpiod_set_value(dmic_en, 1);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ gpiod_set_value(dmic_en, 0);
+ break;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops dmic_dai_ops = {
+ .trigger = dmic_daiops_trigger,
+};
+
static struct snd_soc_dai_driver dmic_dai = {
.name = "dmic-hifi",
.capture = {
@@ -38,8 +68,23 @@ static struct snd_soc_dai_driver dmic_dai = {
| SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE,
},
+ .ops = &dmic_dai_ops,
};
+static int dmic_codec_probe(struct snd_soc_codec *codec)
+{
+ struct gpio_desc *dmic_en;
+
+ dmic_en = devm_gpiod_get_optional(codec->dev,
+ "dmicen", GPIOD_OUT_LOW);
+ if (IS_ERR(dmic_en))
+ return PTR_ERR(dmic_en);
+
+ snd_soc_codec_set_drvdata(codec, dmic_en);
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
SND_SOC_NOPM, 0, 0),
@@ -50,7 +95,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"DMIC AIF", NULL, "DMic"},
};
-static struct snd_soc_codec_driver soc_dmic = {
+static const struct snd_soc_codec_driver soc_dmic = {
+ .probe = dmic_codec_probe,
.component_driver = {
.dapm_widgets = dmic_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets),
@@ -73,9 +119,15 @@ static int dmic_dev_remove(struct platform_device *pdev)
MODULE_ALIAS("platform:dmic-codec");
+static const struct of_device_id dmic_dev_match[] = {
+ {.compatible = "dmic-codec"},
+ {}
+};
+
static struct platform_driver dmic_driver = {
.driver = {
.name = "dmic-codec",
+ .of_match_table = dmic_dev_match,
},
.probe = dmic_dev_probe,
.remove = dmic_dev_remove,
diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c
index 25ede825d349..3869025754d8 100644
--- a/sound/soc/codecs/es7134.c
+++ b/sound/soc/codecs/es7134.c
@@ -69,7 +69,7 @@ static const struct snd_soc_dapm_route es7134_dapm_routes[] = {
{ "AOUTR", NULL, "DAC" },
};
-static struct snd_soc_codec_driver es7134_codec_driver = {
+static const struct snd_soc_codec_driver es7134_codec_driver = {
.component_driver = {
.dapm_widgets = es7134_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(es7134_dapm_widgets),
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c
index ecc02449c569..da2d353af5ba 100644
--- a/sound/soc/codecs/es8316.c
+++ b/sound/soc/codecs/es8316.c
@@ -502,7 +502,7 @@ static int es8316_mute(struct snd_soc_dai *dai, int mute)
#define ES8316_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE)
-static struct snd_soc_dai_ops es8316_ops = {
+static const struct snd_soc_dai_ops es8316_ops = {
.startup = es8316_pcm_startup,
.hw_params = es8316_pcm_hw_params,
.set_fmt = es8316_set_dai_fmt,
@@ -554,7 +554,7 @@ static int es8316_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_es8316 = {
+static const struct snd_soc_codec_driver soc_codec_dev_es8316 = {
.probe = es8316_probe,
.idle_bias_off = true,
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index ed7cc42d1ee2..bcdb8914ec16 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -830,7 +830,7 @@ const struct regmap_config es8328_regmap_config = {
};
EXPORT_SYMBOL_GPL(es8328_regmap_config);
-static struct snd_soc_codec_driver es8328_codec_driver = {
+static const struct snd_soc_codec_driver es8328_codec_driver = {
.probe = es8328_codec_probe,
.suspend = es8328_suspend,
.resume = es8328_resume,
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index bc2e74ff3b2d..e824d47cc22b 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -121,6 +121,10 @@ struct hdac_hdmi_dai_port_map {
struct hdac_hdmi_cvt *cvt;
};
+struct hdac_hdmi_drv_data {
+ unsigned int vendor_nid;
+};
+
struct hdac_hdmi_priv {
struct hdac_hdmi_dai_port_map dai_map[HDA_MAX_CVTS];
struct list_head pin_list;
@@ -131,6 +135,7 @@ struct hdac_hdmi_priv {
int num_ports;
struct mutex pin_mutex;
struct hdac_chmap chmap;
+ struct hdac_hdmi_drv_data *drv_data;
};
static struct hdac_hdmi_pcm *
@@ -1321,6 +1326,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
}
#define INTEL_VENDOR_NID 0x08
+#define INTEL_GLK_VENDOR_NID 0x0b
#define INTEL_GET_VENDOR_VERB 0xf81
#define INTEL_SET_VENDOR_VERB 0x781
#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
@@ -1329,14 +1335,17 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
{
unsigned int vendor_param;
+ struct hdac_ext_device *edev = to_ehdac_device(hdac);
+ struct hdac_hdmi_priv *hdmi = edev->private_data;
+ unsigned int vendor_nid = hdmi->drv_data->vendor_nid;
- vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+ vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
INTEL_GET_VENDOR_VERB, 0);
if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)
return;
vendor_param |= INTEL_EN_ALL_PIN_CVTS;
- vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+ vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
INTEL_SET_VENDOR_VERB, vendor_param);
if (vendor_param == -1)
return;
@@ -1345,22 +1354,25 @@ static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac)
static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac)
{
unsigned int vendor_param;
+ struct hdac_ext_device *edev = to_ehdac_device(hdac);
+ struct hdac_hdmi_priv *hdmi = edev->private_data;
+ unsigned int vendor_nid = hdmi->drv_data->vendor_nid;
- vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+ vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
INTEL_GET_VENDOR_VERB, 0);
if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)
return;
/* enable DP1.2 mode */
vendor_param |= INTEL_EN_DP12;
- vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0,
+ vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0,
INTEL_SET_VENDOR_VERB, vendor_param);
if (vendor_param == -1)
return;
}
-static struct snd_soc_dai_ops hdmi_dai_ops = {
+static const struct snd_soc_dai_ops hdmi_dai_ops = {
.startup = hdac_hdmi_pcm_open,
.shutdown = hdac_hdmi_pcm_close,
.hw_params = hdac_hdmi_set_hw_params,
@@ -1858,7 +1870,7 @@ static void hdmi_codec_complete(struct device *dev)
#define hdmi_codec_complete NULL
#endif
-static struct snd_soc_codec_driver hdmi_hda_codec = {
+static const struct snd_soc_codec_driver hdmi_hda_codec = {
.probe = hdmi_codec_probe,
.remove = hdmi_codec_remove,
.idle_bias_off = true,
@@ -1927,6 +1939,14 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
return port->eld.info.spk_alloc;
}
+static struct hdac_hdmi_drv_data intel_glk_drv_data = {
+ .vendor_nid = INTEL_GLK_VENDOR_NID,
+};
+
+static struct hdac_hdmi_drv_data intel_drv_data = {
+ .vendor_nid = INTEL_VENDOR_NID,
+};
+
static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
{
struct hdac_device *codec = &edev->hdac;
@@ -1935,6 +1955,8 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
struct hdac_ext_link *hlink = NULL;
int num_dais = 0;
int ret = 0;
+ struct hdac_driver *hdrv = drv_to_hdac_driver(codec->dev.driver);
+ const struct hda_device_id *hdac_id = hdac_get_device_id(codec, hdrv);
/* hold the ref while we probe */
hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev));
@@ -1956,6 +1978,12 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached;
hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc;
+ if (hdac_id->driver_data)
+ hdmi_priv->drv_data =
+ (struct hdac_hdmi_drv_data *)hdac_id->driver_data;
+ else
+ hdmi_priv->drv_data = &intel_drv_data;
+
dev_set_drvdata(&codec->dev, edev);
INIT_LIST_HEAD(&hdmi_priv->pin_list);
@@ -2127,7 +2155,8 @@ static const struct hda_device_id hdmi_list[] = {
HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),
HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0),
HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0),
- HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", 0),
+ HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI",
+ &intel_glk_drv_data),
{}
};
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 22ed0dc88f0a..3abf82563408 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -67,14 +67,14 @@ struct hdmi_codec_cea_spk_alloc {
};
/* Channel maps stereo HDMI */
-const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
+static const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
{ .channels = 2,
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
{ }
};
/* Channel maps for multi-channel playbacks, up to 8 n_ch */
-const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
+static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
{ .channels = 2, /* CA_ID 0x00 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
{ .channels = 4, /* CA_ID 0x01 */
@@ -326,7 +326,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
{
int i;
- const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
+ static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
[0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
[4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
};
@@ -340,7 +340,7 @@ static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
return spk_mask;
}
-void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp)
+static void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp)
{
u8 spk_alloc;
unsigned long spk_mask;
@@ -399,18 +399,6 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
return 0;
}
-
-static const struct snd_kcontrol_new hdmi_controls[] = {
- {
- .access = SNDRV_CTL_ELEM_ACCESS_READ |
- SNDRV_CTL_ELEM_ACCESS_VOLATILE,
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "ELD",
- .info = hdmi_eld_ctl_info,
- .get = hdmi_eld_ctl_get,
- },
-};
-
static int hdmi_codec_new_stream(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -668,6 +656,16 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
{
struct snd_soc_dai_driver *drv = dai->driver;
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+ struct snd_kcontrol *kctl;
+ struct snd_kcontrol_new hdmi_eld_ctl = {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "ELD",
+ .info = hdmi_eld_ctl_info,
+ .get = hdmi_eld_ctl_get,
+ .device = rtd->pcm->device,
+ };
int ret;
dev_dbg(dai->dev, "%s()\n", __func__);
@@ -686,14 +684,19 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
- return 0;
+ /* add ELD ctl with the device number corresponding to the PCM stream */
+ kctl = snd_ctl_new1(&hdmi_eld_ctl, dai->component);
+ if (!kctl)
+ return -ENOMEM;
+
+ return snd_ctl_add(rtd->card->snd_card, kctl);
}
-static struct snd_soc_dai_driver hdmi_i2s_dai = {
+static const struct snd_soc_dai_driver hdmi_i2s_dai = {
.name = "i2s-hifi",
.id = DAI_ID_I2S,
.playback = {
- .stream_name = "Playback",
+ .stream_name = "I2S Playback",
.channels_min = 2,
.channels_max = 8,
.rates = HDMI_RATES,
@@ -708,7 +711,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.name = "spdif-hifi",
.id = DAI_ID_SPDIF,
.playback = {
- .stream_name = "Playback",
+ .stream_name = "SPDIF Playback",
.channels_min = 2,
.channels_max = 2,
.rates = HDMI_RATES,
@@ -730,10 +733,8 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
return ret;
}
-static struct snd_soc_codec_driver hdmi_codec = {
+static const struct snd_soc_codec_driver hdmi_codec = {
.component_driver = {
- .controls = hdmi_controls,
- .num_controls = ARRAY_SIZE(hdmi_controls),
.dapm_widgets = hdmi_widgets,
.num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
.dapm_routes = hdmi_routes,
diff --git a/sound/soc/codecs/ics43432.c b/sound/soc/codecs/ics43432.c
index dd850b93938d..651206273f36 100644
--- a/sound/soc/codecs/ics43432.c
+++ b/sound/soc/codecs/ics43432.c
@@ -37,7 +37,7 @@ static struct snd_soc_dai_driver ics43432_dai = {
},
};
-static struct snd_soc_codec_driver ics43432_codec_driver = {
+static const struct snd_soc_codec_driver ics43432_codec_driver = {
};
static int ics43432_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c
index b918ba5c8ce5..6b59b6f08298 100644
--- a/sound/soc/codecs/inno_rk3036.c
+++ b/sound/soc/codecs/inno_rk3036.c
@@ -310,7 +310,7 @@ static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream,
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops rk3036_codec_dai_ops = {
+static const struct snd_soc_dai_ops rk3036_codec_dai_ops = {
.set_fmt = rk3036_codec_dai_set_fmt,
.hw_params = rk3036_codec_dai_hw_params,
};
@@ -376,7 +376,7 @@ static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static struct snd_soc_codec_driver rk3036_codec_driver = {
+static const struct snd_soc_codec_driver rk3036_codec_driver = {
.probe = rk3036_codec_probe,
.remove = rk3036_codec_remove,
.set_bias_level = rk3036_codec_set_bias_level,
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index a4b0eded984a..5ca99280ae00 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -1087,7 +1087,7 @@ static struct snd_soc_dai_driver isabelle_dai[] = {
},
};
-static struct snd_soc_codec_driver soc_codec_dev_isabelle = {
+static const struct snd_soc_codec_driver soc_codec_dev_isabelle = {
.set_bias_level = isabelle_set_bias_level,
.component_driver = {
.controls = isabelle_snd_controls,
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 0290fab383da..6324ccdc8a5c 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -293,7 +293,7 @@ static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
+static const struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
.probe = jz4740_codec_dev_probe,
.set_bias_level = jz4740_codec_set_bias_level,
.suspend_bias_off = true,
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 558de1053f73..1e964079642a 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -100,7 +100,7 @@ static const struct snd_soc_dapm_route lm4857_routes[] = {
{ "EP", "Earpiece", "Mode" },
};
-static struct snd_soc_component_driver lm4857_component_driver = {
+static const struct snd_soc_component_driver lm4857_component_driver = {
.controls = lm4857_controls,
.num_controls = ARRAY_SIZE(lm4857_controls),
.dapm_widgets = lm4857_dapm_widgets,
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 8d413c2677cc..41e09d1287b8 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -1389,7 +1389,7 @@ static struct snd_soc_dai_driver lm49453_dai[] = {
},
};
-static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
+static const struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
.set_bias_level = lm49453_set_bias_level,
.component_driver = {
.controls = lm49453_snd_controls,
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c
index 5b82e26cd5d1..7017c0389e73 100644
--- a/sound/soc/codecs/max9768.c
+++ b/sound/soc/codecs/max9768.c
@@ -151,7 +151,7 @@ static int max9768_probe(struct snd_soc_component *component)
return 0;
}
-static struct snd_soc_component_driver max9768_component_driver = {
+static const struct snd_soc_component_driver max9768_component_driver = {
.probe = max9768_probe,
.controls = max9768_volume,
.num_controls = ARRAY_SIZE(max9768_volume),
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 72f77455582e..f0bb830874e5 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1698,7 +1698,7 @@ static int max98088_remove(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
+static const struct snd_soc_codec_driver soc_codec_dev_max98088 = {
.probe = max98088_probe,
.remove = max98088_remove,
.set_bias_level = max98088_set_bias_level,
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 66828480d484..13bcfb1ef9b4 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2499,7 +2499,7 @@ static void max98090_seq_notifier(struct snd_soc_dapm_context *dapm,
}
}
-static struct snd_soc_codec_driver soc_codec_dev_max98090 = {
+static const struct snd_soc_codec_driver soc_codec_dev_max98090 = {
.probe = max98090_probe,
.remove = max98090_remove,
.seq_notifier = max98090_seq_notifier,
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 6f8a757876ed..5ead87d2ab1d 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2102,7 +2102,7 @@ static int max98095_remove(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_max98095 = {
+static const struct snd_soc_codec_driver soc_codec_dev_max98095 = {
.probe = max98095_probe,
.remove = max98095_remove,
.suspend = max98095_suspend,
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c
index 6a6b68a4cb52..426ed2dae6ca 100644
--- a/sound/soc/codecs/max98357a.c
+++ b/sound/soc/codecs/max98357a.c
@@ -72,7 +72,7 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver max98357a_codec_driver = {
+static const struct snd_soc_codec_driver max98357a_codec_driver = {
.probe = max98357a_codec_probe,
.component_driver = {
.dapm_widgets = max98357a_dapm_widgets,
diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c
index 781be9ba8dba..7bc2a17c1e94 100644
--- a/sound/soc/codecs/max98371.c
+++ b/sound/soc/codecs/max98371.c
@@ -349,12 +349,14 @@ static struct snd_soc_dai_driver max98371_dai[] = {
};
static const struct snd_soc_codec_driver max98371_codec = {
- .controls = max98371_snd_controls,
- .num_controls = ARRAY_SIZE(max98371_snd_controls),
- .dapm_routes = max98371_audio_map,
- .num_dapm_routes = ARRAY_SIZE(max98371_audio_map),
- .dapm_widgets = max98371_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets),
+ .component_driver = {
+ .controls = max98371_snd_controls,
+ .num_controls = ARRAY_SIZE(max98371_snd_controls),
+ .dapm_routes = max98371_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(max98371_audio_map),
+ .dapm_widgets = max98371_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets),
+ },
};
static const struct regmap_config max98371_regmap = {
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index 0610840733d1..a3dfc918c278 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -301,7 +301,7 @@ static int max9850_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
+static const struct snd_soc_codec_driver soc_codec_dev_max9850 = {
.probe = max9850_probe,
.set_bias_level = max9850_set_bias_level,
.suspend_bias_off = true,
diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c
index 499bdbfd0a2d..a2dc6a47f466 100644
--- a/sound/soc/codecs/max9860.c
+++ b/sound/soc/codecs/max9860.c
@@ -534,7 +534,7 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
-static struct snd_soc_codec_driver max9860_codec_driver = {
+static const struct snd_soc_codec_driver max9860_codec_driver = {
.set_bias_level = max9860_set_bias_level,
.idle_bias_off = true,
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c
index 2a40a69a7513..2f60924fe919 100644
--- a/sound/soc/codecs/max9867.c
+++ b/sound/soc/codecs/max9867.c
@@ -350,7 +350,7 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
return 0;
}
-static struct snd_soc_dai_ops max9867_dai_ops = {
+static const struct snd_soc_dai_ops max9867_dai_ops = {
.set_fmt = max9867_dai_set_fmt,
.set_sysclk = max9867_set_dai_sysclk,
.prepare = max9867_prepare,
@@ -413,7 +413,7 @@ static int max9867_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver max9867_codec = {
+static const struct snd_soc_codec_driver max9867_codec = {
.probe = max9867_probe,
.component_driver = {
.controls = max9867_snd_controls,
diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c
index 1eff7e0b092e..03d07bf4d942 100644
--- a/sound/soc/codecs/max98926.c
+++ b/sound/soc/codecs/max98926.c
@@ -213,8 +213,8 @@ static bool max98926_readable_register(struct device *dev, unsigned int reg)
}
};
-DECLARE_TLV_DB_SCALE(max98926_spk_tlv, -600, 100, 0);
-DECLARE_TLV_DB_RANGE(max98926_current_tlv,
+static DECLARE_TLV_DB_SCALE(max98926_spk_tlv, -600, 100, 0);
+static DECLARE_TLV_DB_RANGE(max98926_current_tlv,
0, 11, TLV_DB_SCALE_ITEM(20, 20, 0),
12, 15, TLV_DB_SCALE_ITEM(320, 40, 0),
);
@@ -459,7 +459,7 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream,
#define MAX98926_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-static struct snd_soc_dai_ops max98926_dai_ops = {
+static const struct snd_soc_dai_ops max98926_dai_ops = {
.set_fmt = max98926_dai_set_fmt,
.hw_params = max98926_dai_hw_params,
};
@@ -496,7 +496,7 @@ static int max98926_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_max98926 = {
+static const struct snd_soc_codec_driver soc_codec_dev_max98926 = {
.probe = max98926_probe,
.component_driver = {
.controls = max98926_snd_controls,
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
index b5ee29499e16..d9dbbe72f8ad 100644
--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -44,9 +44,9 @@ static struct reg_default max98927_reg[] = {
{MAX98927_R0011_CLK_MON, 0x00},
{MAX98927_R0012_WDOG_CTRL, 0x00},
{MAX98927_R0013_WDOG_RST, 0x00},
- {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x00},
- {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x00},
- {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x00},
+ {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x75},
+ {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x8c},
+ {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x08},
{MAX98927_R0017_PIN_CFG, 0x55},
{MAX98927_R0018_PCM_RX_EN_A, 0x00},
{MAX98927_R0019_PCM_RX_EN_B, 0x00},
@@ -82,14 +82,14 @@ static struct reg_default max98927_reg[] = {
{MAX98927_R003A_AMP_EN, 0x00},
{MAX98927_R003B_SPK_SRC_SEL, 0x00},
{MAX98927_R003C_SPK_GAIN, 0x00},
- {MAX98927_R003D_SSM_CFG, 0x01},
+ {MAX98927_R003D_SSM_CFG, 0x04},
{MAX98927_R003E_MEAS_EN, 0x00},
{MAX98927_R003F_MEAS_DSP_CFG, 0x04},
{MAX98927_R0040_BOOST_CTRL0, 0x00},
{MAX98927_R0041_BOOST_CTRL3, 0x00},
{MAX98927_R0042_BOOST_CTRL1, 0x00},
{MAX98927_R0043_MEAS_ADC_CFG, 0x00},
- {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x00},
+ {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x01},
{MAX98927_R0045_MEAS_ADC_BASE_LSB, 0x00},
{MAX98927_R0046_ADC_CH0_DIVIDE, 0x00},
{MAX98927_R0047_ADC_CH1_DIVIDE, 0x00},
@@ -159,7 +159,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
mode = MAX98927_PCM_MASTER_MODE_MASTER;
break;
default:
- dev_err(codec->dev, "DAI clock mode unsupported");
+ dev_err(codec->dev, "DAI clock mode unsupported\n");
return -EINVAL;
}
@@ -175,7 +175,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE;
break;
default:
- dev_err(codec->dev, "DAI invert mode unsupported");
+ dev_err(codec->dev, "DAI invert mode unsupported\n");
return -EINVAL;
}
@@ -311,7 +311,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
break;
default:
- dev_err(codec->dev, "format unsupported %d",
+ dev_err(codec->dev, "format unsupported %d\n",
params_format(params));
goto err;
}
@@ -418,11 +418,6 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
regmap_update_bits(max98927->regmap,
MAX98927_R003A_AMP_EN,
MAX98927_AMP_EN_MASK, 1);
- /* enable VMON and IMON */
- regmap_update_bits(max98927->regmap,
- MAX98927_R003E_MEAS_EN,
- MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN,
- MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN);
regmap_update_bits(max98927->regmap,
MAX98927_R00FF_GLOBAL_SHDN,
MAX98927_GLOBAL_EN_MASK, 1);
@@ -434,10 +429,6 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
regmap_update_bits(max98927->regmap,
MAX98927_R003A_AMP_EN,
MAX98927_AMP_EN_MASK, 0);
- /* disable VMON and IMON */
- regmap_update_bits(max98927->regmap,
- MAX98927_R003E_MEAS_EN,
- MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0);
break;
default:
return 0;
@@ -456,14 +447,24 @@ static const struct soc_enum dai_sel_enum =
static const struct snd_kcontrol_new max98927_dai_controls =
SOC_DAPM_ENUM("DAI Sel", dai_sel_enum);
+static const struct snd_kcontrol_new max98927_vi_control =
+ SOC_DAPM_SINGLE("Switch", MAX98927_R003F_MEAS_DSP_CFG, 2, 1, 0);
+
static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
- SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN,
0, 0, max98927_dac_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0,
&max98927_dai_controls),
SND_SOC_DAPM_OUTPUT("BE_OUT"),
+ SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0,
+ MAX98927_R003E_MEAS_EN, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0,
+ MAX98927_R003E_MEAS_EN, 1, 0),
+ SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0,
+ &max98927_vi_control),
+ SND_SOC_DAPM_SIGGEN("VMON"),
+ SND_SOC_DAPM_SIGGEN("IMON"),
};
static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
@@ -495,6 +496,13 @@ static bool max98927_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3:
+ case MAX98927_R004C_MEAS_ADC_CH0_READ:
+ case MAX98927_R004D_MEAS_ADC_CH1_READ:
+ case MAX98927_R004E_MEAS_ADC_CH2_READ:
+ case MAX98927_R0051_BROWNOUT_STATUS:
+ case MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ:
+ case MAX98927_R01FF_REV_ID:
+ case MAX98927_R0100_SOFT_RESET:
return true;
default:
return false;
@@ -543,11 +551,16 @@ static const struct snd_kcontrol_new max98927_snd_controls[] = {
};
static const struct snd_soc_dapm_route max98927_audio_map[] = {
- {"Amp Enable", NULL, "DAI_OUT"},
+ /* Plabyack */
{"DAI Sel Mux", "Left", "Amp Enable"},
{"DAI Sel Mux", "Right", "Amp Enable"},
{"DAI Sel Mux", "LeftRight", "Amp Enable"},
{"BE_OUT", NULL, "DAI Sel Mux"},
+ /* Capture */
+ { "VI Sense", "Switch", "VMON" },
+ { "VI Sense", "Switch", "IMON" },
+ { "Voltage Sense", NULL, "VI Sense" },
+ { "Current Sense", NULL, "VI Sense" },
};
static struct snd_soc_dai_driver max98927_dai[] = {
@@ -577,7 +590,6 @@ static int max98927_probe(struct snd_soc_codec *codec)
max98927->codec = codec;
codec->control_data = max98927->regmap;
- codec->cache_bypass = 1;
/* Software Reset */
regmap_write(max98927->regmap,
@@ -694,6 +706,31 @@ static int max98927_probe(struct snd_soc_codec *codec)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int max98927_suspend(struct device *dev)
+{
+ struct max98927_priv *max98927 = dev_get_drvdata(dev);
+
+ regcache_cache_only(max98927->regmap, true);
+ regcache_mark_dirty(max98927->regmap);
+ return 0;
+}
+static int max98927_resume(struct device *dev)
+{
+ struct max98927_priv *max98927 = dev_get_drvdata(dev);
+
+ regmap_write(max98927->regmap,
+ MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET);
+ regcache_cache_only(max98927->regmap, false);
+ regcache_sync(max98927->regmap);
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops max98927_pm = {
+ SET_SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume)
+};
+
static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
.probe = max98927_probe,
.component_driver = {
@@ -721,14 +758,14 @@ static void max98927_slot_config(struct i2c_client *i2c,
struct max98927_priv *max98927)
{
int value;
+ struct device *dev = &i2c->dev;
- if (!of_property_read_u32(i2c->dev.of_node,
- "vmon-slot-no", &value))
+ if (!device_property_read_u32(dev, "vmon-slot-no", &value))
max98927->v_l_slot = value & 0xF;
else
max98927->v_l_slot = 0;
- if (!of_property_read_u32(i2c->dev.of_node,
- "imon-slot-no", &value))
+
+ if (!device_property_read_u32(dev, "imon-slot-no", &value))
max98927->i_l_slot = value & 0xF;
else
max98927->i_l_slot = 1;
@@ -827,7 +864,7 @@ static struct i2c_driver max98927_i2c_driver = {
.name = "max98927",
.of_match_table = of_match_ptr(max98927_of_match),
.acpi_match_table = ACPI_PTR(max98927_acpi_match),
- .pm = NULL,
+ .pm = &max98927_pm,
},
.probe = max98927_i2c_probe,
.remove = max98927_i2c_remove,
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 90562703dcfd..4fd8d1dc4eef 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -733,7 +733,7 @@ static struct regmap *mc13783_get_regmap(struct device *dev)
return dev_get_regmap(dev->parent, NULL);
}
-static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
+static const struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
.probe = mc13783_probe,
.remove = mc13783_remove,
.get_regmap = mc13783_get_regmap,
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 69e5e18880c5..5cc960d8211e 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -537,7 +537,7 @@ static int ml26124_probe(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
+static const struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
.probe = ml26124_probe,
.set_bias_level = ml26124_set_bias_level,
.suspend_bias_off = true,
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 5710fd440bcd..549c269acc7d 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -12,9 +12,16 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>
+#include <sound/jack.h>
#define CDC_D_REVISION1 (0xf000)
#define CDC_D_PERPH_SUBTYPE (0xf005)
+#define CDC_D_INT_EN_SET (0x015)
+#define CDC_D_INT_EN_CLR (0x016)
+#define MBHC_SWITCH_INT BIT(7)
+#define MBHC_MIC_ELECTRICAL_INS_REM_DET BIT(6)
+#define MBHC_BUTTON_PRESS_DET BIT(5)
+#define MBHC_BUTTON_RELEASE_DET BIT(4)
#define CDC_D_CDC_RST_CTL (0xf046)
#define RST_CTL_DIG_SW_RST_N_MASK BIT(7)
#define RST_CTL_DIG_SW_RST_N_RESET 0
@@ -37,6 +44,8 @@
#define DIG_CLK_CTL_RXD1_CLK_EN BIT(0)
#define DIG_CLK_CTL_RXD2_CLK_EN BIT(1)
#define DIG_CLK_CTL_RXD3_CLK_EN BIT(2)
+#define DIG_CLK_CTL_D_MBHC_CLK_EN_MASK BIT(3)
+#define DIG_CLK_CTL_D_MBHC_CLK_EN BIT(3)
#define DIG_CLK_CTL_TXD_CLK_EN BIT(4)
#define DIG_CLK_CTL_NCP_CLK_EN_MASK BIT(6)
#define DIG_CLK_CTL_NCP_CLK_EN BIT(6)
@@ -93,8 +102,12 @@
#define MICB_1_EN_TX3_GND_SEL_TX_GND 0
#define CDC_A_MICB_1_VAL (0xf141)
+#define MICB_MIN_VAL 1600
+#define MICB_STEP_SIZE 50
+#define MICB_VOLTAGE_REGVAL(v) ((v - MICB_MIN_VAL)/MICB_STEP_SIZE)
#define MICB_1_VAL_MICB_OUT_VAL_MASK GENMASK(7, 3)
#define MICB_1_VAL_MICB_OUT_VAL_V2P70V ((0x16) << 3)
+#define MICB_1_VAL_MICB_OUT_VAL_V1P80V ((0x4) << 3)
#define CDC_A_MICB_1_CTL (0xf142)
#define MICB_1_CTL_CFILT_REF_SEL_MASK BIT(1)
@@ -128,8 +141,51 @@
#define MICB_1_INT_TX3_INT_PULLUP_EN_TX1N_TO_GND 0
#define CDC_A_MICB_2_EN (0xf144)
+#define CDC_A_MICB_2_EN_ENABLE BIT(7)
+#define CDC_A_MICB_2_PULL_DOWN_EN_MASK BIT(5)
+#define CDC_A_MICB_2_PULL_DOWN_EN BIT(5)
#define CDC_A_TX_1_2_ATEST_CTL_2 (0xf145)
#define CDC_A_MASTER_BIAS_CTL (0xf146)
+#define CDC_A_MBHC_DET_CTL_1 (0xf147)
+#define CDC_A_MBHC_DET_CTL_L_DET_EN BIT(7)
+#define CDC_A_MBHC_DET_CTL_GND_DET_EN BIT(6)
+#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION BIT(5)
+#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_REMOVAL (0)
+#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK BIT(5)
+#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT (5)
+#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO BIT(4)
+#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_MANUAL BIT(3)
+#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_MASK GENMASK(4, 3)
+#define CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN BIT(2)
+#define CDC_A_MBHC_DET_CTL_2 (0xf150)
+#define CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 (BIT(7) | BIT(6))
+#define CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD BIT(5)
+#define CDC_A_PLUG_TYPE_MASK GENMASK(4, 3)
+#define CDC_A_HPHL_PLUG_TYPE_NO BIT(4)
+#define CDC_A_GND_PLUG_TYPE_NO BIT(3)
+#define CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN_MASK BIT(0)
+#define CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN BIT(0)
+#define CDC_A_MBHC_FSM_CTL (0xf151)
+#define CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN BIT(7)
+#define CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK BIT(7)
+#define CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA (0x3 << 4)
+#define CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK GENMASK(6, 4)
+#define CDC_A_MBHC_DBNC_TIMER (0xf152)
+#define CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS BIT(3)
+#define CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS (0x9 << 4)
+#define CDC_A_MBHC_BTN0_ZDET_CTL_0 (0xf153)
+#define CDC_A_MBHC_BTN1_ZDET_CTL_1 (0xf154)
+#define CDC_A_MBHC_BTN2_ZDET_CTL_2 (0xf155)
+#define CDC_A_MBHC_BTN3_CTL (0xf156)
+#define CDC_A_MBHC_BTN4_CTL (0xf157)
+#define CDC_A_MBHC_BTN_VREF_FINE_SHIFT (2)
+#define CDC_A_MBHC_BTN_VREF_FINE_MASK GENMASK(4, 2)
+#define CDC_A_MBHC_BTN_VREF_COARSE_MASK GENMASK(7, 5)
+#define CDC_A_MBHC_BTN_VREF_COARSE_SHIFT (5)
+#define CDC_A_MBHC_BTN_VREF_MASK (CDC_A_MBHC_BTN_VREF_COARSE_MASK | \
+ CDC_A_MBHC_BTN_VREF_FINE_MASK)
+#define CDC_A_MBHC_RESULT_1 (0xf158)
+#define CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK GENMASK(4, 0)
#define CDC_A_TX_1_EN (0xf160)
#define CDC_A_TX_2_EN (0xf161)
#define CDC_A_TX_1_2_TEST_CTL_1 (0xf162)
@@ -213,18 +269,37 @@
#define MSM8916_WCD_ANALOG_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S24_LE)
+static int btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4;
+static int hs_jack_mask = SND_JACK_HEADPHONE | SND_JACK_HEADSET;
+
static const char * const supply_names[] = {
"vdd-cdc-io",
"vdd-cdc-tx-rx-cx",
};
+#define MBHC_MAX_BUTTONS (5)
+
struct pm8916_wcd_analog_priv {
u16 pmic_rev;
u16 codec_version;
+ bool mbhc_btn_enabled;
+ /* special event to detect accessory type */
+ bool mbhc_btn0_pressed;
+ bool detect_accessory_type;
struct clk *mclk;
+ struct snd_soc_codec *codec;
struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
+ struct snd_soc_jack *jack;
+ bool hphl_jack_type_normally_open;
+ bool gnd_jack_type_normally_open;
+ /* Voltage threshold when internal current source of 100uA is used */
+ u32 vref_btn_cs[MBHC_MAX_BUTTONS];
+ /* Voltage threshold when microphone bias is ON */
+ u32 vref_btn_micb[MBHC_MAX_BUTTONS];
unsigned int micbias1_cap_mode;
unsigned int micbias2_cap_mode;
+ unsigned int micbias_mv;
};
static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" };
@@ -265,18 +340,25 @@ static const struct snd_kcontrol_new pm8916_wcd_analog_snd_controls[] = {
static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
{
+ struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+
snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
MICB_1_CTL_EXT_PRECHARG_EN_MASK |
MICB_1_CTL_INT_PRECHARG_BYP_MASK,
MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL
| MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
- snd_soc_write(codec, CDC_A_MICB_1_VAL, MICB_1_VAL_MICB_OUT_VAL_V2P70V);
- /*
- * Special headset needs MICBIAS as 2.7V so wait for
- * 50 msec for the MICBIAS to reach 2.7 volts.
- */
- msleep(50);
+ if (wcd->micbias_mv) {
+ snd_soc_write(codec, CDC_A_MICB_1_VAL,
+ MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
+ /*
+ * Special headset needs MICBIAS as 2.7V so wait for
+ * 50 msec for the MICBIAS to reach 2.7 volts.
+ */
+ if (wcd->micbias_mv >= 2700)
+ msleep(50);
+ }
+
snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
MICB_1_CTL_EXT_PRECHARG_EN_MASK |
MICB_1_CTL_INT_PRECHARG_BYP_MASK, 0);
@@ -361,6 +443,97 @@ static int pm8916_wcd_analog_enable_micbias_int1(struct
wcd->micbias1_cap_mode);
}
+static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
+{
+ struct snd_soc_codec *codec = wcd->codec;
+ u32 plug_type = 0;
+ u32 int_en_mask;
+
+ snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1,
+ CDC_A_MBHC_DET_CTL_L_DET_EN |
+ CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION |
+ CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO |
+ CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN);
+
+ if (wcd->hphl_jack_type_normally_open)
+ plug_type |= CDC_A_HPHL_PLUG_TYPE_NO;
+
+ if (wcd->gnd_jack_type_normally_open)
+ plug_type |= CDC_A_GND_PLUG_TYPE_NO;
+
+ snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2,
+ CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 |
+ CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD |
+ plug_type |
+ CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN);
+
+
+ snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER,
+ CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS |
+ CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS);
+
+ /* enable MBHC clock */
+ snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL,
+ DIG_CLK_CTL_D_MBHC_CLK_EN_MASK,
+ DIG_CLK_CTL_D_MBHC_CLK_EN);
+
+ int_en_mask = MBHC_SWITCH_INT;
+ if (wcd->mbhc_btn_enabled)
+ int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET;
+
+ snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0);
+ snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
+ wcd->mbhc_btn0_pressed = false;
+ wcd->detect_accessory_type = true;
+}
+
+static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
+ bool micbias2_enabled)
+{
+ struct snd_soc_codec *codec = priv->codec;
+ u32 coarse, fine, reg_val, reg_addr;
+ int *vrefs, i;
+
+ if (!micbias2_enabled) { /* use internal 100uA Current source */
+ /* Enable internal 2.2k Internal Rbias Resistor */
+ snd_soc_update_bits(codec, CDC_A_MICB_1_INT_RBIAS,
+ MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
+ MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
+ /* Remove pull down on MIC BIAS2 */
+ snd_soc_update_bits(codec, CDC_A_MICB_2_EN,
+ CDC_A_MICB_2_PULL_DOWN_EN_MASK,
+ 0);
+ /* enable 100uA internal current source */
+ snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL,
+ CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK,
+ CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA);
+ }
+ snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL,
+ CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK,
+ CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN);
+
+ if (micbias2_enabled)
+ vrefs = &priv->vref_btn_micb[0];
+ else
+ vrefs = &priv->vref_btn_cs[0];
+
+ /* program vref ranges for all the buttons */
+ reg_addr = CDC_A_MBHC_BTN0_ZDET_CTL_0;
+ for (i = 0; i < MBHC_MAX_BUTTONS; i++) {
+ /* split mv in to coarse parts of 100mv & fine parts of 12mv */
+ coarse = (vrefs[i] / 100);
+ fine = ((vrefs[i] % 100) / 12);
+ reg_val = (coarse << CDC_A_MBHC_BTN_VREF_COARSE_SHIFT) |
+ (fine << CDC_A_MBHC_BTN_VREF_FINE_SHIFT);
+ snd_soc_update_bits(codec, reg_addr,
+ CDC_A_MBHC_BTN_VREF_MASK,
+ reg_val);
+ reg_addr++;
+ }
+
+ return 0;
+}
+
static int pm8916_wcd_analog_enable_micbias_int2(struct
snd_soc_dapm_widget
*w, struct snd_kcontrol
@@ -369,6 +542,15 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ pm8916_mbhc_configure_bias(wcd, true);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pm8916_mbhc_configure_bias(wcd, false);
+ break;
+ }
+
return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg,
wcd->micbias2_cap_mode);
}
@@ -536,6 +718,14 @@ static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec)
snd_soc_write(codec, wcd_reg_defaults_2_0[reg].reg,
wcd_reg_defaults_2_0[reg].def);
+ priv->codec = codec;
+
+ snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL,
+ RST_CTL_DIG_SW_RST_N_MASK,
+ RST_CTL_DIG_SW_RST_N_REMOVE_RESET);
+
+ pm8916_wcd_setup_mbhc(priv);
+
return 0;
}
@@ -543,6 +733,9 @@ static int pm8916_wcd_analog_remove(struct snd_soc_codec *codec)
{
struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev);
+ snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL,
+ RST_CTL_DIG_SW_RST_N_MASK, 0);
+
return regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
priv->supplies);
}
@@ -731,32 +924,128 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("A_MCLK2", CDC_D_CDC_TOP_CLK_CTL, 3, 0, NULL, 0),
};
+static int pm8916_wcd_analog_set_jack(struct snd_soc_codec *codec,
+ struct snd_soc_jack *jack,
+ void *data)
+{
+ struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
+
+ wcd->jack = jack;
+
+ return 0;
+}
+
static struct regmap *pm8916_get_regmap(struct device *dev)
{
return dev_get_regmap(dev->parent, NULL);
}
-static int pm8916_wcd_analog_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
+static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg)
{
- snd_soc_update_bits(dai->codec, CDC_D_CDC_RST_CTL,
- RST_CTL_DIG_SW_RST_N_MASK,
- RST_CTL_DIG_SW_RST_N_REMOVE_RESET);
+ struct pm8916_wcd_analog_priv *priv = arg;
- return 0;
+ if (priv->detect_accessory_type) {
+ struct snd_soc_codec *codec = priv->codec;
+ u32 val = snd_soc_read(codec, CDC_A_MBHC_RESULT_1);
+
+ /* check if its BTN0 thats released */
+ if ((val != -1) && !(val & CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK))
+ priv->mbhc_btn0_pressed = false;
+
+ } else {
+ snd_soc_jack_report(priv->jack, 0, btn_mask);
+ }
+
+ return IRQ_HANDLED;
}
-static void pm8916_wcd_analog_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
+static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
{
- snd_soc_update_bits(dai->codec, CDC_D_CDC_RST_CTL,
- RST_CTL_DIG_SW_RST_N_MASK, 0);
+ struct pm8916_wcd_analog_priv *priv = arg;
+ struct snd_soc_codec *codec = priv->codec;
+ u32 btn_result;
+
+ btn_result = snd_soc_read(codec, CDC_A_MBHC_RESULT_1) &
+ CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK;
+
+ switch (btn_result) {
+ case 0xf:
+ snd_soc_jack_report(priv->jack, SND_JACK_BTN_4, btn_mask);
+ break;
+ case 0x7:
+ snd_soc_jack_report(priv->jack, SND_JACK_BTN_3, btn_mask);
+ break;
+ case 0x3:
+ snd_soc_jack_report(priv->jack, SND_JACK_BTN_2, btn_mask);
+ break;
+ case 0x1:
+ snd_soc_jack_report(priv->jack, SND_JACK_BTN_1, btn_mask);
+ break;
+ case 0x0:
+ /* handle BTN_0 specially for type detection */
+ if (priv->detect_accessory_type)
+ priv->mbhc_btn0_pressed = true;
+ else
+ snd_soc_jack_report(priv->jack,
+ SND_JACK_BTN_0, btn_mask);
+ break;
+ default:
+ dev_err(codec->dev,
+ "Unexpected button press result (%x)", btn_result);
+ break;
+ }
+
+ return IRQ_HANDLED;
}
-static struct snd_soc_dai_ops pm8916_wcd_analog_dai_ops = {
- .startup = pm8916_wcd_analog_startup,
- .shutdown = pm8916_wcd_analog_shutdown,
-};
+static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg)
+{
+ struct pm8916_wcd_analog_priv *priv = arg;
+ struct snd_soc_codec *codec = priv->codec;
+ bool ins = false;
+
+ if (snd_soc_read(codec, CDC_A_MBHC_DET_CTL_1) &
+ CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK)
+ ins = true;
+
+ /* Set the detection type appropriately */
+ snd_soc_update_bits(codec, CDC_A_MBHC_DET_CTL_1,
+ CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK,
+ (!ins << CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT));
+
+
+ if (ins) { /* hs insertion */
+ bool micbias_enabled = false;
+
+ if (snd_soc_read(codec, CDC_A_MICB_2_EN) &
+ CDC_A_MICB_2_EN_ENABLE)
+ micbias_enabled = true;
+
+ pm8916_mbhc_configure_bias(priv, micbias_enabled);
+
+ /*
+ * if only a btn0 press event is receive just before
+ * insert event then its a 3 pole headphone else if
+ * both press and release event received then its
+ * a headset.
+ */
+ if (priv->mbhc_btn0_pressed)
+ snd_soc_jack_report(priv->jack,
+ SND_JACK_HEADPHONE, hs_jack_mask);
+ else
+ snd_soc_jack_report(priv->jack,
+ SND_JACK_HEADSET, hs_jack_mask);
+
+ priv->detect_accessory_type = false;
+
+ } else { /* removal */
+ snd_soc_jack_report(priv->jack, 0, hs_jack_mask);
+ priv->detect_accessory_type = true;
+ priv->mbhc_btn0_pressed = false;
+ }
+
+ return IRQ_HANDLED;
+}
static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = {
[0] = {
@@ -769,7 +1058,6 @@ static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = {
.channels_min = 1,
.channels_max = 3,
},
- .ops = &pm8916_wcd_analog_dai_ops,
},
[1] = {
.name = "pm8916_wcd_analog_pdm_tx",
@@ -781,13 +1069,13 @@ static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = {
.channels_min = 1,
.channels_max = 4,
},
- .ops = &pm8916_wcd_analog_dai_ops,
},
};
-static struct snd_soc_codec_driver pm8916_wcd_analog = {
+static const struct snd_soc_codec_driver pm8916_wcd_analog = {
.probe = pm8916_wcd_analog_probe,
.remove = pm8916_wcd_analog_remove,
+ .set_jack = pm8916_wcd_analog_set_jack,
.get_regmap = pm8916_get_regmap,
.component_driver = {
.controls = pm8916_wcd_analog_snd_controls,
@@ -802,6 +1090,7 @@ static struct snd_soc_codec_driver pm8916_wcd_analog = {
static int pm8916_wcd_analog_parse_dt(struct device *dev,
struct pm8916_wcd_analog_priv *priv)
{
+ int rval;
if (of_property_read_bool(dev->of_node, "qcom,micbias1-ext-cap"))
priv->micbias1_cap_mode = MICB_1_EN_EXT_BYP_CAP;
@@ -813,6 +1102,42 @@ static int pm8916_wcd_analog_parse_dt(struct device *dev,
else
priv->micbias2_cap_mode = MICB_1_EN_NO_EXT_BYP_CAP;
+ of_property_read_u32(dev->of_node, "qcom,micbias-lvl",
+ &priv->micbias_mv);
+
+ if (of_property_read_bool(dev->of_node,
+ "qcom,hphl-jack-type-normally-open"))
+ priv->hphl_jack_type_normally_open = true;
+ else
+ priv->hphl_jack_type_normally_open = false;
+
+ if (of_property_read_bool(dev->of_node,
+ "qcom,gnd-jack-type-normally-open"))
+ priv->gnd_jack_type_normally_open = true;
+ else
+ priv->gnd_jack_type_normally_open = false;
+
+ priv->mbhc_btn_enabled = true;
+ rval = of_property_read_u32_array(dev->of_node,
+ "qcom,mbhc-vthreshold-low",
+ &priv->vref_btn_cs[0],
+ MBHC_MAX_BUTTONS);
+ if (rval < 0) {
+ priv->mbhc_btn_enabled = false;
+ } else {
+ rval = of_property_read_u32_array(dev->of_node,
+ "qcom,mbhc-vthreshold-high",
+ &priv->vref_btn_micb[0],
+ MBHC_MAX_BUTTONS);
+ if (rval < 0)
+ priv->mbhc_btn_enabled = false;
+ }
+
+ if (!priv->mbhc_btn_enabled)
+ dev_err(dev,
+ "DT property missing, MBHC btn detection disabled\n");
+
+
return 0;
}
@@ -820,7 +1145,7 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
{
struct pm8916_wcd_analog_priv *priv;
struct device *dev = &pdev->dev;
- int ret, i;
+ int ret, i, irq;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -852,6 +1177,48 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
return ret;
}
+ irq = platform_get_irq_byname(pdev, "mbhc_switch_int");
+ if (irq < 0) {
+ dev_err(dev, "failed to get mbhc switch irq\n");
+ return irq;
+ }
+
+ ret = devm_request_irq(dev, irq, pm8916_mbhc_switch_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ "mbhc switch irq", priv);
+ if (ret)
+ dev_err(dev, "cannot request mbhc switch irq\n");
+
+ if (priv->mbhc_btn_enabled) {
+ irq = platform_get_irq_byname(pdev, "mbhc_but_press_det");
+ if (irq < 0) {
+ dev_err(dev, "failed to get button press irq\n");
+ return irq;
+ }
+
+ ret = devm_request_irq(dev, irq, mbhc_btn_press_irq_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "mbhc btn press irq", priv);
+ if (ret)
+ dev_err(dev, "cannot request mbhc button press irq\n");
+
+ irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det");
+ if (irq < 0) {
+ dev_err(dev, "failed to get button release irq\n");
+ return irq;
+ }
+
+ ret = devm_request_irq(dev, irq, mbhc_btn_release_irq_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "mbhc btn release irq", priv);
+ if (ret)
+ dev_err(dev, "cannot request mbhc button release irq\n");
+
+ }
+
dev_set_drvdata(dev, priv);
return snd_soc_register_codec(dev, &pm8916_wcd_analog,
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c
index f690442af8c9..66df8f810f0d 100644
--- a/sound/soc/codecs/msm8916-wcd-digital.c
+++ b/sound/soc/codecs/msm8916-wcd-digital.c
@@ -218,6 +218,8 @@ static const char *const rx_mix1_text[] = {
static const char *const dec_mux_text[] = {
"ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2"
};
+
+static const char *const cic_mux_text[] = { "AMIC", "DMIC" };
static const char *const rx_mix2_text[] = { "ZERO", "IIR1", "IIR2" };
static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" };
@@ -256,11 +258,21 @@ static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE(
static const struct soc_enum dec2_mux_enum = SOC_ENUM_SINGLE(
LPASS_CDC_CONN_TX_B1_CTL, 3, 6, dec_mux_text);
+/* CIC */
+static const struct soc_enum cic1_mux_enum = SOC_ENUM_SINGLE(
+ LPASS_CDC_TX1_MUX_CTL, 0, 2, cic_mux_text);
+static const struct soc_enum cic2_mux_enum = SOC_ENUM_SINGLE(
+ LPASS_CDC_TX2_MUX_CTL, 0, 2, cic_mux_text);
+
/* RDAC2 MUX */
static const struct snd_kcontrol_new dec1_mux = SOC_DAPM_ENUM(
"DEC1 MUX Mux", dec1_mux_enum);
static const struct snd_kcontrol_new dec2_mux = SOC_DAPM_ENUM(
"DEC2 MUX Mux", dec2_mux_enum);
+static const struct snd_kcontrol_new cic1_mux = SOC_DAPM_ENUM(
+ "CIC1 MUX Mux", cic1_mux_enum);
+static const struct snd_kcontrol_new cic2_mux = SOC_DAPM_ENUM(
+ "CIC2 MUX Mux", cic2_mux_enum);
static const struct snd_kcontrol_new rx_mix1_inp1_mux = SOC_DAPM_ENUM(
"RX1 MIX1 INP1 Mux", rx_mix1_inp_enum[0]);
static const struct snd_kcontrol_new rx_mix1_inp2_mux = SOC_DAPM_ENUM(
@@ -500,6 +512,8 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0,
&rx3_mix1_inp3_mux),
+ SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux),
+ SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux),
/* TX */
SND_SOC_DAPM_MIXER("ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -536,6 +550,8 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
/* Connectivity Clock */
SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, LPASS_CDC_CLK_OTHR_CTL, 2, 0,
NULL, 0),
+ SND_SOC_DAPM_MIC("Digital Mic1", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic2", NULL),
};
@@ -568,6 +584,15 @@ static int msm8916_wcd_digital_codec_probe(struct snd_soc_codec *codec)
return 0;
}
+static int msm8916_wcd_digital_codec_set_sysclk(struct snd_soc_codec *codec,
+ int clk_id, int source,
+ unsigned int freq, int dir)
+{
+ struct msm8916_wcd_digital_priv *p = dev_get_drvdata(codec->dev);
+
+ return clk_set_rate(p->mclk, freq);
+}
+
static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -646,6 +671,11 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
{"AIF1 Capture", NULL, "I2S TX2"},
{"AIF1 Capture", NULL, "I2S TX3"},
+ {"CIC1 MUX", "DMIC", "DEC1 MUX"},
+ {"CIC1 MUX", "AMIC", "DEC1 MUX"},
+ {"CIC2 MUX", "DMIC", "DEC2 MUX"},
+ {"CIC2 MUX", "AMIC", "DEC2 MUX"},
+
/* Decimator Inputs */
{"DEC1 MUX", "DMIC1", "DMIC1"},
{"DEC1 MUX", "DMIC2", "DMIC2"},
@@ -664,8 +694,8 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
{"DMIC1", NULL, "DMIC_CLK"},
{"DMIC2", NULL, "DMIC_CLK"},
- {"I2S TX1", NULL, "DEC1 MUX"},
- {"I2S TX2", NULL, "DEC2 MUX"},
+ {"I2S TX1", NULL, "CIC1 MUX"},
+ {"I2S TX2", NULL, "CIC2 MUX"},
{"I2S TX1", NULL, "TX_I2S_CLK"},
{"I2S TX2", NULL, "TX_I2S_CLK"},
@@ -788,7 +818,7 @@ static void msm8916_wcd_digital_shutdown(struct snd_pcm_substream *substream,
LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 0);
}
-static struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = {
+static const struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = {
.startup = msm8916_wcd_digital_startup,
.shutdown = msm8916_wcd_digital_shutdown,
.hw_params = msm8916_wcd_digital_hw_params,
@@ -821,8 +851,9 @@ static struct snd_soc_dai_driver msm8916_wcd_digital_dai[] = {
},
};
-static struct snd_soc_codec_driver msm8916_wcd_digital = {
+static const struct snd_soc_codec_driver msm8916_wcd_digital = {
.probe = msm8916_wcd_digital_codec_probe,
+ .set_sysclk = msm8916_wcd_digital_codec_set_sysclk,
.component_driver = {
.controls = msm8916_wcd_digital_snd_controls,
.num_controls = ARRAY_SIZE(msm8916_wcd_digital_snd_controls),
diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c
index c8bcb1db966d..f9c9933acffb 100644
--- a/sound/soc/codecs/nau8540.c
+++ b/sound/soc/codecs/nau8540.c
@@ -735,7 +735,7 @@ static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver nau8540_codec_driver = {
+static const struct snd_soc_codec_driver nau8540_codec_driver = {
.set_sysclk = nau8540_set_sysclk,
.set_pll = nau8540_set_pll,
.suspend = nau8540_suspend,
diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c
index e45518629968..c8e2451ae0a3 100644
--- a/sound/soc/codecs/nau8810.c
+++ b/sound/soc/codecs/nau8810.c
@@ -808,7 +808,7 @@ static const struct regmap_config nau8810_regmap_config = {
.num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults),
};
-static struct snd_soc_codec_driver nau8810_codec_driver = {
+static const struct snd_soc_codec_driver nau8810_codec_driver = {
.set_bias_level = nau8810_set_bias_level,
.suspend_bias_off = true,
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c
index 3a309b18035e..0240759f951c 100644
--- a/sound/soc/codecs/nau8824.c
+++ b/sound/soc/codecs/nau8824.c
@@ -1469,7 +1469,7 @@ static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver nau8824_codec_driver = {
+static const struct snd_soc_codec_driver nau8824_codec_driver = {
.probe = nau8824_codec_probe,
.set_sysclk = nau8824_set_sysclk,
.set_pll = nau8824_set_pll,
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index 46a30eaa7ace..714ce17da717 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -260,11 +260,11 @@ static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
if (timeout) {
ret = down_timeout(&nau8825->xtalk_sem, timeout);
if (ret < 0)
- dev_warn(nau8825->dev, "Acquire semaphone timeout\n");
+ dev_warn(nau8825->dev, "Acquire semaphore timeout\n");
} else {
ret = down_interruptible(&nau8825->xtalk_sem);
if (ret < 0)
- dev_warn(nau8825->dev, "Acquire semaphone fail\n");
+ dev_warn(nau8825->dev, "Acquire semaphore fail\n");
}
return ret;
@@ -1299,7 +1299,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
NAU8825_I2S_DL_MASK, val_len);
- /* Release the semaphone. */
+ /* Release the semaphore. */
nau8825_sema_release(nau8825);
return 0;
@@ -1361,7 +1361,7 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
NAU8825_I2S_MS_MASK, ctrl2_val);
- /* Release the semaphone. */
+ /* Release the semaphore. */
nau8825_sema_release(nau8825);
return 0;
@@ -2140,7 +2140,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
break;
case NAU8825_CLK_MCLK:
- /* Acquire the semaphone to synchronize the playback and
+ /* Acquire the semaphore to synchronize the playback and
* interrupt handler. In order to avoid the playback inter-
* fered by cross talk process, the driver make the playback
* preparation halted until cross talk process finish.
@@ -2150,7 +2150,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
/* MCLK not changed by clock tree */
regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_MCLK_SRC_MASK, 0);
- /* Release the semaphone. */
+ /* Release the semaphore. */
nau8825_sema_release(nau8825);
ret = nau8825_mclk_prepare(nau8825, freq);
@@ -2188,7 +2188,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
break;
case NAU8825_CLK_FLL_MCLK:
- /* Acquire the semaphone to synchronize the playback and
+ /* Acquire the semaphore to synchronize the playback and
* interrupt handler. In order to avoid the playback inter-
* fered by cross talk process, the driver make the playback
* preparation halted until cross talk process finish.
@@ -2201,7 +2201,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
regmap_update_bits(regmap, NAU8825_REG_FLL3,
NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK,
NAU8825_FLL_CLK_SRC_MCLK | 0);
- /* Release the semaphone. */
+ /* Release the semaphore. */
nau8825_sema_release(nau8825);
ret = nau8825_mclk_prepare(nau8825, freq);
@@ -2210,7 +2210,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
break;
case NAU8825_CLK_FLL_BLK:
- /* Acquire the semaphone to synchronize the playback and
+ /* Acquire the semaphore to synchronize the playback and
* interrupt handler. In order to avoid the playback inter-
* fered by cross talk process, the driver make the playback
* preparation halted until cross talk process finish.
@@ -2226,7 +2226,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK,
NAU8825_FLL_CLK_SRC_BLK |
(0xf << NAU8825_GAIN_ERR_SFT));
- /* Release the semaphone. */
+ /* Release the semaphore. */
nau8825_sema_release(nau8825);
if (nau8825->mclk_freq) {
@@ -2236,7 +2236,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
break;
case NAU8825_CLK_FLL_FS:
- /* Acquire the semaphone to synchronize the playback and
+ /* Acquire the semaphore to synchronize the playback and
* interrupt handler. In order to avoid the playback inter-
* fered by cross talk process, the driver make the playback
* preparation halted until cross talk process finish.
@@ -2252,7 +2252,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK,
NAU8825_FLL_CLK_SRC_FS |
(0xf << NAU8825_GAIN_ERR_SFT));
- /* Release the semaphone. */
+ /* Release the semaphore. */
nau8825_sema_release(nau8825);
if (nau8825->mclk_freq) {
@@ -2388,7 +2388,7 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
return 0;
}
-static struct snd_soc_codec_driver nau8825_codec_driver = {
+static const struct snd_soc_codec_driver nau8825_codec_driver = {
.probe = nau8825_codec_probe,
.remove = nau8825_codec_remove,
.set_sysclk = nau8825_set_sysclk,
@@ -2563,7 +2563,7 @@ static int nau8825_i2c_probe(struct i2c_client *i2c,
return PTR_ERR(nau8825->regmap);
nau8825->dev = dev;
nau8825->irq = i2c->irq;
- /* Initiate parameters, semaphone and work queue which are needed in
+ /* Initiate parameters, semaphore and work queue which are needed in
* cross talk suppression measurment function.
*/
nau8825->xtalk_state = NAU8825_XTALK_DONE;
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c
index 0b14efab6280..c7e28dd2e815 100644
--- a/sound/soc/codecs/pcm1681.c
+++ b/sound/soc/codecs/pcm1681.c
@@ -288,7 +288,7 @@ static const struct regmap_config pcm1681_regmap = {
.readable_reg = pcm1681_accessible_reg,
};
-static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = {
+static const struct snd_soc_codec_driver soc_codec_dev_pcm1681 = {
.component_driver = {
.controls = pcm1681_controls,
.num_controls = ARRAY_SIZE(pcm1681_controls),
diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c
index b813a154ddd9..82a3d9db32cb 100644
--- a/sound/soc/codecs/pcm179x.c
+++ b/sound/soc/codecs/pcm179x.c
@@ -205,7 +205,7 @@ const struct regmap_config pcm179x_regmap_config = {
};
EXPORT_SYMBOL_GPL(pcm179x_regmap_config);
-static struct snd_soc_codec_driver soc_codec_dev_pcm179x = {
+static const struct snd_soc_codec_driver soc_codec_dev_pcm179x = {
.component_driver = {
.controls = pcm179x_controls,
.num_controls = ARRAY_SIZE(pcm179x_controls),
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 708af05486f6..e59d8ffb93bd 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -98,7 +98,7 @@ static struct snd_soc_dai_driver pcm3008_dai = {
},
};
-static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
+static const struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
.component_driver = {
.dapm_widgets = pcm3008_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets),
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 72b19e62f626..f1005a31c709 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -1344,7 +1344,7 @@ static struct snd_soc_dai_driver pcm512x_dai = {
.ops = &pcm512x_dai_ops,
};
-static struct snd_soc_codec_driver pcm512x_codec_driver = {
+static const struct snd_soc_codec_driver pcm512x_codec_driver = {
.set_bias_level = pcm512x_set_bias_level,
.idle_bias_off = true,
diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c
new file mode 100644
index 000000000000..8f92e5c4dd9d
--- /dev/null
+++ b/sound/soc/codecs/rt274.c
@@ -0,0 +1,1229 @@
+/*
+ * rt274.c -- RT274 ALSA SoC audio codec driver
+ *
+ * Copyright 2017 Realtek Semiconductor Corp.
+ * Author: Bard Liao <bardliao@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/dmi.h>
+#include <linux/acpi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/jack.h>
+#include <linux/workqueue.h>
+
+#include "rl6347a.h"
+#include "rt274.h"
+
+#define RT274_VENDOR_ID 0x10ec0274
+
+struct rt274_priv {
+ struct reg_default *index_cache;
+ int index_cache_size;
+ struct regmap *regmap;
+ struct snd_soc_codec *codec;
+ struct i2c_client *i2c;
+ struct snd_soc_jack *jack;
+ struct delayed_work jack_detect_work;
+ int sys_clk;
+ int clk_id;
+ int fs;
+ bool master;
+};
+
+static const struct reg_default rt274_index_def[] = {
+ { 0x00, 0x1004 },
+ { 0x01, 0xaaaa },
+ { 0x02, 0x88aa },
+ { 0x03, 0x0002 },
+ { 0x04, 0xaa09 },
+ { 0x05, 0x0700 },
+ { 0x06, 0x6110 },
+ { 0x07, 0x0200 },
+ { 0x08, 0xa807 },
+ { 0x09, 0x0021 },
+ { 0x0a, 0x7770 },
+ { 0x0b, 0x7770 },
+ { 0x0c, 0x002b },
+ { 0x0d, 0x2420 },
+ { 0x0e, 0x65c0 },
+ { 0x0f, 0x7770 },
+ { 0x10, 0x0420 },
+ { 0x11, 0x7418 },
+ { 0x12, 0x6bd0 },
+ { 0x13, 0x645f },
+ { 0x14, 0x0400 },
+ { 0x15, 0x8ccc },
+ { 0x16, 0x4c50 },
+ { 0x17, 0xff00 },
+ { 0x18, 0x0003 },
+ { 0x19, 0x2c11 },
+ { 0x1a, 0x830b },
+ { 0x1b, 0x4e4b },
+ { 0x1c, 0x0000 },
+ { 0x1d, 0x0000 },
+ { 0x1e, 0x0000 },
+ { 0x1f, 0x0000 },
+ { 0x20, 0x51ff },
+ { 0x21, 0x8000 },
+ { 0x22, 0x8f00 },
+ { 0x23, 0x88f4 },
+ { 0x24, 0x0000 },
+ { 0x25, 0x0000 },
+ { 0x26, 0x0000 },
+ { 0x27, 0x0000 },
+ { 0x28, 0x0000 },
+ { 0x29, 0x3000 },
+ { 0x2a, 0x0000 },
+ { 0x2b, 0x0000 },
+ { 0x2c, 0x0f00 },
+ { 0x2d, 0x100f },
+ { 0x2e, 0x2902 },
+ { 0x2f, 0xe280 },
+ { 0x30, 0x1000 },
+ { 0x31, 0x8400 },
+ { 0x32, 0x5aaa },
+ { 0x33, 0x8420 },
+ { 0x34, 0xa20c },
+ { 0x35, 0x096a },
+ { 0x36, 0x5757 },
+ { 0x37, 0xfe05 },
+ { 0x38, 0x4901 },
+ { 0x39, 0x110a },
+ { 0x3a, 0x0010 },
+ { 0x3b, 0x60d9 },
+ { 0x3c, 0xf214 },
+ { 0x3d, 0xc2ba },
+ { 0x3e, 0xa928 },
+ { 0x3f, 0x0000 },
+ { 0x40, 0x9800 },
+ { 0x41, 0x0000 },
+ { 0x42, 0x2000 },
+ { 0x43, 0x3d90 },
+ { 0x44, 0x4900 },
+ { 0x45, 0x5289 },
+ { 0x46, 0x0004 },
+ { 0x47, 0xa47a },
+ { 0x48, 0xd049 },
+ { 0x49, 0x0049 },
+ { 0x4a, 0xa83b },
+ { 0x4b, 0x0777 },
+ { 0x4c, 0x065c },
+ { 0x4d, 0x7fff },
+ { 0x4e, 0x7fff },
+ { 0x4f, 0x0000 },
+ { 0x50, 0x0000 },
+ { 0x51, 0x0000 },
+ { 0x52, 0xbf5f },
+ { 0x53, 0x3320 },
+ { 0x54, 0xcc00 },
+ { 0x55, 0x0000 },
+ { 0x56, 0x3f00 },
+ { 0x57, 0x0000 },
+ { 0x58, 0x0000 },
+ { 0x59, 0x0000 },
+ { 0x5a, 0x1300 },
+ { 0x5b, 0x005f },
+ { 0x5c, 0x0000 },
+ { 0x5d, 0x1001 },
+ { 0x5e, 0x1000 },
+ { 0x5f, 0x0000 },
+ { 0x60, 0x5554 },
+ { 0x61, 0xffc0 },
+ { 0x62, 0xa000 },
+ { 0x63, 0xd010 },
+ { 0x64, 0x0000 },
+ { 0x65, 0x3fb1 },
+ { 0x66, 0x1881 },
+ { 0x67, 0xc810 },
+ { 0x68, 0x2000 },
+ { 0x69, 0xfff0 },
+ { 0x6a, 0x0300 },
+ { 0x6b, 0x5060 },
+ { 0x6c, 0x0000 },
+ { 0x6d, 0x0000 },
+ { 0x6e, 0x0c25 },
+ { 0x6f, 0x0c0b },
+ { 0x70, 0x8000 },
+ { 0x71, 0x4008 },
+ { 0x72, 0x0000 },
+ { 0x73, 0x0800 },
+ { 0x74, 0xa28f },
+ { 0x75, 0xa050 },
+ { 0x76, 0x7fe8 },
+ { 0x77, 0xdb8c },
+ { 0x78, 0x0000 },
+ { 0x79, 0x0000 },
+ { 0x7a, 0x2a96 },
+ { 0x7b, 0x800f },
+ { 0x7c, 0x0200 },
+ { 0x7d, 0x1600 },
+ { 0x7e, 0x0000 },
+ { 0x7f, 0x0000 },
+};
+#define INDEX_CACHE_SIZE ARRAY_SIZE(rt274_index_def)
+
+static const struct reg_default rt274_reg[] = {
+ { 0x00170500, 0x00000400 },
+ { 0x00220000, 0x00000031 },
+ { 0x00239000, 0x00000057 },
+ { 0x0023a000, 0x00000057 },
+ { 0x00270500, 0x00000400 },
+ { 0x00370500, 0x00000400 },
+ { 0x00870500, 0x00000400 },
+ { 0x00920000, 0x00000031 },
+ { 0x00935000, 0x00000097 },
+ { 0x00936000, 0x00000097 },
+ { 0x00970500, 0x00000400 },
+ { 0x00b37000, 0x00000400 },
+ { 0x00b37200, 0x00000400 },
+ { 0x00b37300, 0x00000400 },
+ { 0x00c37000, 0x00000400 },
+ { 0x00c37100, 0x00000400 },
+ { 0x01270500, 0x00000400 },
+ { 0x01370500, 0x00000400 },
+ { 0x01371f00, 0x411111f0 },
+ { 0x01937000, 0x00000000 },
+ { 0x01970500, 0x00000400 },
+ { 0x02050000, 0x0000001b },
+ { 0x02139000, 0x00000080 },
+ { 0x0213a000, 0x00000080 },
+ { 0x02170100, 0x00000001 },
+ { 0x02170500, 0x00000400 },
+ { 0x02170700, 0x00000000 },
+ { 0x02270100, 0x00000000 },
+ { 0x02370100, 0x00000000 },
+ { 0x01970700, 0x00000020 },
+ { 0x00830000, 0x00000097 },
+ { 0x00930000, 0x00000097 },
+ { 0x01270700, 0x00000000 },
+};
+
+static bool rt274_volatile_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case 0 ... 0xff:
+ case RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID):
+ case RT274_GET_HP_SENSE:
+ case RT274_GET_MIC_SENSE:
+ case RT274_PROC_COEF:
+ case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_MIC, 0):
+ case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT0, 0):
+ case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT1, 0):
+ case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN1, 0):
+ case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN2, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC1, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC2, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_MIC, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE1, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE2, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN1, 0):
+ case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN2, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC2, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_MIC, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE1, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE2, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_MIC, 0):
+ case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_INLINE_CMD, 0):
+ return true;
+ default:
+ return false;
+ }
+
+
+}
+
+static bool rt274_readable_register(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case 0 ... 0xff:
+ case RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID):
+ case RT274_GET_HP_SENSE:
+ case RT274_GET_MIC_SENSE:
+ case RT274_SET_AUDIO_POWER:
+ case RT274_SET_HPO_POWER:
+ case RT274_SET_DMIC1_POWER:
+ case RT274_LOUT_MUX:
+ case RT274_HPO_MUX:
+ case RT274_ADC0_MUX:
+ case RT274_ADC1_MUX:
+ case RT274_SET_MIC:
+ case RT274_SET_PIN_HPO:
+ case RT274_SET_PIN_LOUT3:
+ case RT274_SET_PIN_DMIC1:
+ case RT274_SET_AMP_GAIN_HPO:
+ case RT274_SET_DMIC2_DEFAULT:
+ case RT274_DAC0L_GAIN:
+ case RT274_DAC0R_GAIN:
+ case RT274_DAC1L_GAIN:
+ case RT274_DAC1R_GAIN:
+ case RT274_ADCL_GAIN:
+ case RT274_ADCR_GAIN:
+ case RT274_MIC_GAIN:
+ case RT274_HPOL_GAIN:
+ case RT274_HPOR_GAIN:
+ case RT274_LOUTL_GAIN:
+ case RT274_LOUTR_GAIN:
+ case RT274_DAC_FORMAT:
+ case RT274_ADC_FORMAT:
+ case RT274_COEF_INDEX:
+ case RT274_PROC_COEF:
+ case RT274_SET_AMP_GAIN_ADC_IN1:
+ case RT274_SET_AMP_GAIN_ADC_IN2:
+ case RT274_SET_POWER(RT274_DAC_OUT0):
+ case RT274_SET_POWER(RT274_DAC_OUT1):
+ case RT274_SET_POWER(RT274_ADC_IN1):
+ case RT274_SET_POWER(RT274_ADC_IN2):
+ case RT274_SET_POWER(RT274_DMIC2):
+ case RT274_SET_POWER(RT274_MIC):
+ case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_MIC, 0):
+ case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT0, 0):
+ case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT1, 0):
+ case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN1, 0):
+ case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN2, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC1, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC2, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_MIC, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE1, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE2, 0):
+ case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN1, 0):
+ case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN2, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC2, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_MIC, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE1, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE2, 0):
+ case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_HP_OUT, 0):
+ case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_MIC, 0):
+ case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_INLINE_CMD, 0):
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifdef CONFIG_PM
+static void rt274_index_sync(struct snd_soc_codec *codec)
+{
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ for (i = 0; i < INDEX_CACHE_SIZE; i++) {
+ snd_soc_write(codec, rt274->index_cache[i].reg,
+ rt274->index_cache[i].def);
+ }
+}
+#endif
+
+static int rt274_jack_detect(struct rt274_priv *rt274, bool *hp, bool *mic)
+{
+ unsigned int buf;
+
+ *hp = false;
+ *mic = false;
+
+ if (!rt274->codec)
+ return -EINVAL;
+
+ regmap_read(rt274->regmap, RT274_GET_HP_SENSE, &buf);
+ *hp = buf & 0x80000000;
+ regmap_read(rt274->regmap, RT274_GET_MIC_SENSE, &buf);
+ *mic = buf & 0x80000000;
+
+ pr_debug("*hp = %d *mic = %d\n", *hp, *mic);
+
+ return 0;
+}
+
+static void rt274_jack_detect_work(struct work_struct *work)
+{
+ struct rt274_priv *rt274 =
+ container_of(work, struct rt274_priv, jack_detect_work.work);
+ int status = 0;
+ bool hp = false;
+ bool mic = false;
+
+ if (rt274_jack_detect(rt274, &hp, &mic) < 0)
+ return;
+
+ if (hp == true)
+ status |= SND_JACK_HEADPHONE;
+
+ if (mic == true)
+ status |= SND_JACK_MICROPHONE;
+
+ snd_soc_jack_report(rt274->jack, status,
+ SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
+}
+
+static irqreturn_t rt274_irq(int irq, void *data);
+
+static int rt274_mic_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *jack, void *data)
+{
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+
+ if (jack == NULL) {
+ /* Disable jack detection */
+ regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL,
+ RT274_IRQ_EN, RT274_IRQ_DIS);
+
+ return 0;
+ }
+ rt274->jack = jack;
+
+ regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL,
+ RT274_IRQ_EN, RT274_IRQ_EN);
+
+ /* Send an initial report */
+ rt274_irq(0, rt274);
+
+ return 0;
+}
+
+static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0);
+static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
+
+static const struct snd_kcontrol_new rt274_snd_controls[] = {
+ SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT274_DAC0L_GAIN,
+ RT274_DAC0R_GAIN, 0, 0x7f, 0, out_vol_tlv),
+ SOC_DOUBLE_R_TLV("DAC1 Playback Volume", RT274_DAC1L_GAIN,
+ RT274_DAC1R_GAIN, 0, 0x7f, 0, out_vol_tlv),
+ SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT274_ADCL_GAIN,
+ RT274_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv),
+ SOC_DOUBLE_R("ADC0 Capture Switch", RT274_ADCL_GAIN,
+ RT274_ADCR_GAIN, RT274_MUTE_SFT, 1, 1),
+ SOC_SINGLE_TLV("AMIC Volume", RT274_MIC_GAIN,
+ 0, 0x3, 0, mic_vol_tlv),
+};
+
+static const struct snd_kcontrol_new hpol_enable_control =
+ SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_HPOL_GAIN,
+ RT274_MUTE_SFT, 1, 1);
+
+static const struct snd_kcontrol_new hpor_enable_control =
+ SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_HPOR_GAIN,
+ RT274_MUTE_SFT, 1, 1);
+
+static const struct snd_kcontrol_new loutl_enable_control =
+ SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_LOUTL_GAIN,
+ RT274_MUTE_SFT, 1, 1);
+
+static const struct snd_kcontrol_new loutr_enable_control =
+ SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_LOUTR_GAIN,
+ RT274_MUTE_SFT, 1, 1);
+
+/* ADC0 source */
+static const char * const rt274_adc_src[] = {
+ "Mic", "Line1", "Line2", "Dmic"
+};
+
+static SOC_ENUM_SINGLE_DECL(
+ rt274_adc0_enum, RT274_ADC0_MUX, RT274_ADC_SEL_SFT,
+ rt274_adc_src);
+
+static const struct snd_kcontrol_new rt274_adc0_mux =
+ SOC_DAPM_ENUM("ADC 0 source", rt274_adc0_enum);
+
+static SOC_ENUM_SINGLE_DECL(
+ rt274_adc1_enum, RT274_ADC1_MUX, RT274_ADC_SEL_SFT,
+ rt274_adc_src);
+
+static const struct snd_kcontrol_new rt274_adc1_mux =
+ SOC_DAPM_ENUM("ADC 1 source", rt274_adc1_enum);
+
+static const char * const rt274_dac_src[] = {
+ "DAC OUT0", "DAC OUT1"
+};
+/* HP-OUT source */
+static SOC_ENUM_SINGLE_DECL(rt274_hpo_enum, RT274_HPO_MUX,
+ 0, rt274_dac_src);
+
+static const struct snd_kcontrol_new rt274_hpo_mux =
+SOC_DAPM_ENUM("HPO source", rt274_hpo_enum);
+
+/* Line out source */
+static SOC_ENUM_SINGLE_DECL(rt274_lout_enum, RT274_LOUT_MUX,
+ 0, rt274_dac_src);
+
+static const struct snd_kcontrol_new rt274_lout_mux =
+SOC_DAPM_ENUM("LOUT source", rt274_lout_enum);
+
+static const struct snd_soc_dapm_widget rt274_dapm_widgets[] = {
+ /* Input Lines */
+ SND_SOC_DAPM_INPUT("DMIC1 Pin"),
+ SND_SOC_DAPM_INPUT("DMIC2 Pin"),
+ SND_SOC_DAPM_INPUT("MIC"),
+ SND_SOC_DAPM_INPUT("LINE1"),
+ SND_SOC_DAPM_INPUT("LINE2"),
+
+ /* DMIC */
+ SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* ADCs */
+ SND_SOC_DAPM_ADC("ADC 0", NULL, RT274_SET_STREAMID_ADC1, 4, 0),
+ SND_SOC_DAPM_ADC("ADC 1", NULL, RT274_SET_STREAMID_ADC2, 4, 0),
+
+ /* ADC Mux */
+ SND_SOC_DAPM_MUX("ADC 0 Mux", SND_SOC_NOPM, 0, 0,
+ &rt274_adc0_mux),
+ SND_SOC_DAPM_MUX("ADC 1 Mux", SND_SOC_NOPM, 0, 0,
+ &rt274_adc1_mux),
+
+ /* Audio Interface */
+ SND_SOC_DAPM_AIF_IN("AIF1RXL", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("AIF1RXR", "AIF1 Playback", 1, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF1TXL", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF1TXR", "AIF1 Capture", 1, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("AIF2RXL", "AIF1 Playback", 2, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("AIF2RXR", "AIF1 Playback", 3, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF2TXL", "AIF1 Capture", 2, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF2TXR", "AIF1 Capture", 3, SND_SOC_NOPM, 0, 0),
+
+ /* Output Side */
+ /* DACs */
+ SND_SOC_DAPM_DAC("DAC 0", NULL, RT274_SET_STREAMID_DAC0, 4, 0),
+ SND_SOC_DAPM_DAC("DAC 1", NULL, RT274_SET_STREAMID_DAC1, 4, 0),
+
+ /* Output Mux */
+ SND_SOC_DAPM_MUX("HPO Mux", SND_SOC_NOPM, 0, 0, &rt274_hpo_mux),
+ SND_SOC_DAPM_MUX("LOUT Mux", SND_SOC_NOPM, 0, 0, &rt274_lout_mux),
+
+ SND_SOC_DAPM_SUPPLY("HP Power", RT274_SET_PIN_HPO,
+ RT274_SET_PIN_SFT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("LOUT Power", RT274_SET_PIN_LOUT3,
+ RT274_SET_PIN_SFT, 0, NULL, 0),
+
+ /* Output Mixer */
+ SND_SOC_DAPM_PGA("DAC OUT0", SND_SOC_NOPM, 0, 0,
+ NULL, 0),
+ SND_SOC_DAPM_PGA("DAC OUT1", SND_SOC_NOPM, 0, 0,
+ NULL, 0),
+
+ /* Output Pga */
+ SND_SOC_DAPM_SWITCH("LOUT L", SND_SOC_NOPM, 0, 0,
+ &loutl_enable_control),
+ SND_SOC_DAPM_SWITCH("LOUT R", SND_SOC_NOPM, 0, 0,
+ &loutr_enable_control),
+ SND_SOC_DAPM_SWITCH("HPO L", SND_SOC_NOPM, 0, 0,
+ &hpol_enable_control),
+ SND_SOC_DAPM_SWITCH("HPO R", SND_SOC_NOPM, 0, 0,
+ &hpor_enable_control),
+
+ /* Output Lines */
+ SND_SOC_DAPM_OUTPUT("HPO Pin"),
+ SND_SOC_DAPM_OUTPUT("SPDIF"),
+ SND_SOC_DAPM_OUTPUT("LINE3"),
+};
+
+static const struct snd_soc_dapm_route rt274_dapm_routes[] = {
+ {"DMIC1", NULL, "DMIC1 Pin"},
+ {"DMIC2", NULL, "DMIC2 Pin"},
+
+ {"ADC 0 Mux", "Mic", "MIC"},
+ {"ADC 0 Mux", "Dmic", "DMIC1"},
+ {"ADC 0 Mux", "Line1", "LINE1"},
+ {"ADC 0 Mux", "Line2", "LINE2"},
+ {"ADC 1 Mux", "Mic", "MIC"},
+ {"ADC 1 Mux", "Dmic", "DMIC2"},
+ {"ADC 1 Mux", "Line1", "LINE1"},
+ {"ADC 1 Mux", "Line2", "LINE2"},
+
+ {"ADC 0", NULL, "ADC 0 Mux"},
+ {"ADC 1", NULL, "ADC 1 Mux"},
+
+ {"AIF1TXL", NULL, "ADC 0"},
+ {"AIF1TXR", NULL, "ADC 0"},
+ {"AIF2TXL", NULL, "ADC 1"},
+ {"AIF2TXR", NULL, "ADC 1"},
+
+ {"DAC 0", NULL, "AIF1RXL"},
+ {"DAC 0", NULL, "AIF1RXR"},
+ {"DAC 1", NULL, "AIF2RXL"},
+ {"DAC 1", NULL, "AIF2RXR"},
+
+ {"DAC OUT0", NULL, "DAC 0"},
+
+ {"DAC OUT1", NULL, "DAC 1"},
+
+ {"LOUT Mux", "DAC OUT0", "DAC OUT0"},
+ {"LOUT Mux", "DAC OUT1", "DAC OUT1"},
+
+ {"LOUT L", "Switch", "LOUT Mux"},
+ {"LOUT R", "Switch", "LOUT Mux"},
+ {"LOUT L", NULL, "LOUT Power"},
+ {"LOUT R", NULL, "LOUT Power"},
+
+ {"LINE3", NULL, "LOUT L"},
+ {"LINE3", NULL, "LOUT R"},
+
+ {"HPO Mux", "DAC OUT0", "DAC OUT0"},
+ {"HPO Mux", "DAC OUT1", "DAC OUT1"},
+
+ {"HPO L", "Switch", "HPO Mux"},
+ {"HPO R", "Switch", "HPO Mux"},
+ {"HPO L", NULL, "HP Power"},
+ {"HPO R", NULL, "HP Power"},
+
+ {"HPO Pin", NULL, "HPO L"},
+ {"HPO Pin", NULL, "HPO R"},
+};
+
+static int rt274_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+ unsigned int val = 0;
+ int d_len_code = 0, c_len_code = 0;
+
+ switch (params_rate(params)) {
+ /* bit 14 0:48K 1:44.1K */
+ case 44100:
+ case 48000:
+ break;
+ default:
+ dev_err(codec->dev, "Unsupported sample rate %d\n",
+ params_rate(params));
+ return -EINVAL;
+ }
+ switch (rt274->sys_clk) {
+ case 12288000:
+ case 24576000:
+ if (params_rate(params) != 48000) {
+ dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+ params_rate(params), rt274->sys_clk);
+ return -EINVAL;
+ }
+ break;
+ case 11289600:
+ case 22579200:
+ if (params_rate(params) != 44100) {
+ dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n",
+ params_rate(params), rt274->sys_clk);
+ return -EINVAL;
+ }
+ break;
+ }
+
+ if (params_channels(params) <= 16) {
+ /* bit 3:0 Number of Channel */
+ val |= (params_channels(params) - 1);
+ } else {
+ dev_err(codec->dev, "Unsupported channels %d\n",
+ params_channels(params));
+ return -EINVAL;
+ }
+
+ switch (params_width(params)) {
+ /* bit 6:4 Bits per Sample */
+ case 16:
+ d_len_code = 0;
+ c_len_code = 0;
+ val |= (0x1 << 4);
+ break;
+ case 32:
+ d_len_code = 2;
+ c_len_code = 3;
+ val |= (0x4 << 4);
+ break;
+ case 20:
+ d_len_code = 1;
+ c_len_code = 1;
+ val |= (0x2 << 4);
+ break;
+ case 24:
+ d_len_code = 2;
+ c_len_code = 2;
+ val |= (0x3 << 4);
+ break;
+ case 8:
+ d_len_code = 3;
+ c_len_code = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (rt274->master)
+ c_len_code = 0x3;
+
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, 0xc018, d_len_code << 3 | c_len_code << 14);
+ dev_dbg(codec->dev, "format val = 0x%x\n", val);
+
+ snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x407f, val);
+ snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x407f, val);
+
+ return 0;
+}
+
+static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_M);
+ rt274->master = true;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_S);
+ rt274->master = false;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+ RT274_I2S_FMT_MASK, RT274_I2S_FMT_I2S);
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+ RT274_I2S_FMT_MASK, RT274_I2S_FMT_LJ);
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+ RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMA);
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ snd_soc_update_bits(codec, RT274_I2S_CTRL1,
+ RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMB);
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* bit 15 Stream Type 0:PCM 1:Non-PCM */
+ snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x8000, 0);
+ snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x8000, 0);
+
+ return 0;
+}
+
+static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
+ unsigned int freq_in, unsigned int freq_out)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+
+ switch (source) {
+ case RT274_PLL2_S_MCLK:
+ snd_soc_update_bits(codec, RT274_PLL2_CTRL,
+ RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_MCLK);
+ break;
+ default:
+ dev_warn(codec->dev, "invalid pll source, use BCLK\n");
+ case RT274_PLL2_S_BCLK:
+ snd_soc_update_bits(codec, RT274_PLL2_CTRL,
+ RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_BCLK);
+ break;
+ }
+
+ if (source == RT274_PLL2_S_BCLK) {
+ snd_soc_update_bits(codec, RT274_MCLK_CTRL,
+ (0x3 << 12), (0x3 << 12));
+ switch (rt274->fs) {
+ case 50:
+ snd_soc_write(codec, 0x7a, 0xaab6);
+ snd_soc_write(codec, 0x7b, 0x0301);
+ snd_soc_write(codec, 0x7c, 0x04fe);
+ break;
+ case 64:
+ snd_soc_write(codec, 0x7a, 0xaa96);
+ snd_soc_write(codec, 0x7b, 0x8003);
+ snd_soc_write(codec, 0x7c, 0x081e);
+ break;
+ case 128:
+ snd_soc_write(codec, 0x7a, 0xaa96);
+ snd_soc_write(codec, 0x7b, 0x8003);
+ snd_soc_write(codec, 0x7c, 0x080e);
+ break;
+ default:
+ dev_warn(codec->dev, "invalid freq_in, assume 4.8M\n");
+ case 100:
+ snd_soc_write(codec, 0x7a, 0xaab6);
+ snd_soc_write(codec, 0x7b, 0x0301);
+ snd_soc_write(codec, 0x7c, 0x047e);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int rt274_set_dai_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+ unsigned int clk_src, mclk_en;
+
+ dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq);
+
+ switch (clk_id) {
+ case RT274_SCLK_S_MCLK:
+ mclk_en = RT274_MCLK_MODE_EN;
+ clk_src = RT274_CLK_SRC_MCLK;
+ break;
+ case RT274_SCLK_S_PLL1:
+ mclk_en = RT274_MCLK_MODE_DIS;
+ clk_src = RT274_CLK_SRC_MCLK;
+ break;
+ case RT274_SCLK_S_PLL2:
+ mclk_en = RT274_MCLK_MODE_EN;
+ clk_src = RT274_CLK_SRC_PLL2;
+ break;
+ default:
+ mclk_en = RT274_MCLK_MODE_DIS;
+ clk_src = RT274_CLK_SRC_MCLK;
+ dev_warn(codec->dev, "invalid sysclk source, use PLL1\n");
+ break;
+ }
+ snd_soc_update_bits(codec, RT274_MCLK_CTRL,
+ RT274_MCLK_MODE_MASK, mclk_en);
+ snd_soc_update_bits(codec, RT274_CLK_CTRL,
+ RT274_CLK_SRC_MASK, clk_src);
+
+ switch (freq) {
+ case 19200000:
+ if (clk_id == RT274_SCLK_S_MCLK) {
+ dev_err(codec->dev, "Should not use MCLK\n");
+ return -EINVAL;
+ }
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL2, 0x40, 0x40);
+ break;
+ case 24000000:
+ if (clk_id == RT274_SCLK_S_MCLK) {
+ dev_err(codec->dev, "Should not use MCLK\n");
+ return -EINVAL;
+ }
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL2, 0x40, 0x0);
+ break;
+ case 12288000:
+ case 11289600:
+ snd_soc_update_bits(codec,
+ RT274_MCLK_CTRL, 0x1fcf, 0x0008);
+ break;
+ case 24576000:
+ case 22579200:
+ snd_soc_update_bits(codec,
+ RT274_MCLK_CTRL, 0x1fcf, 0x1543);
+ break;
+ default:
+ dev_err(codec->dev, "Unsupported system clock\n");
+ return -EINVAL;
+ }
+
+ rt274->sys_clk = freq;
+ rt274->clk_id = clk_id;
+
+ return 0;
+}
+
+static int rt274_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+ rt274->fs = ratio;
+ if ((ratio / 50) == 0)
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, 0x1000, 0x1000);
+ else
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, 0x1000, 0x0);
+
+
+ return 0;
+}
+
+static int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ if (rx_mask || tx_mask) {
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_EN);
+ } else {
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_DIS);
+ return 0;
+ }
+
+ switch (slots) {
+ case 4:
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_4CH);
+ break;
+ case 2:
+ snd_soc_update_bits(codec,
+ RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_2CH);
+ break;
+ default:
+ dev_err(codec->dev,
+ "Support 2 or 4 slots TDM only\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rt274_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ switch (level) {
+ case SND_SOC_BIAS_PREPARE:
+ if (SND_SOC_BIAS_STANDBY ==
+ snd_soc_codec_get_bias_level(codec)) {
+ snd_soc_write(codec,
+ RT274_SET_AUDIO_POWER, AC_PWRST_D0);
+ }
+ break;
+
+ case SND_SOC_BIAS_STANDBY:
+ snd_soc_write(codec,
+ RT274_SET_AUDIO_POWER, AC_PWRST_D3);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static irqreturn_t rt274_irq(int irq, void *data)
+{
+ struct rt274_priv *rt274 = data;
+ bool hp = false;
+ bool mic = false;
+ int ret, status = 0;
+
+ /* Clear IRQ */
+ regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL,
+ RT274_IRQ_CLR, RT274_IRQ_CLR);
+
+ ret = rt274_jack_detect(rt274, &hp, &mic);
+
+ if (ret == 0) {
+ if (hp == true)
+ status |= SND_JACK_HEADPHONE;
+
+ if (mic == true)
+ status |= SND_JACK_MICROPHONE;
+
+ snd_soc_jack_report(rt274->jack, status,
+ SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
+
+ pm_wakeup_event(&rt274->i2c->dev, 300);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int rt274_probe(struct snd_soc_codec *codec)
+{
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+
+ rt274->codec = codec;
+
+ if (rt274->i2c->irq) {
+ INIT_DELAYED_WORK(&rt274->jack_detect_work,
+ rt274_jack_detect_work);
+ schedule_delayed_work(&rt274->jack_detect_work,
+ msecs_to_jiffies(1250));
+ }
+
+ return 0;
+}
+
+static int rt274_remove(struct snd_soc_codec *codec)
+{
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+
+ cancel_delayed_work_sync(&rt274->jack_detect_work);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int rt274_suspend(struct snd_soc_codec *codec)
+{
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+
+ regcache_cache_only(rt274->regmap, true);
+ regcache_mark_dirty(rt274->regmap);
+
+ return 0;
+}
+
+static int rt274_resume(struct snd_soc_codec *codec)
+{
+ struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec);
+
+ regcache_cache_only(rt274->regmap, false);
+ rt274_index_sync(codec);
+ regcache_sync(rt274->regmap);
+
+ return 0;
+}
+#else
+#define rt274_suspend NULL
+#define rt274_resume NULL
+#endif
+
+#define RT274_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
+#define RT274_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
+
+static const struct snd_soc_dai_ops rt274_aif_dai_ops = {
+ .hw_params = rt274_hw_params,
+ .set_fmt = rt274_set_dai_fmt,
+ .set_sysclk = rt274_set_dai_sysclk,
+ .set_pll = rt274_set_dai_pll,
+ .set_bclk_ratio = rt274_set_bclk_ratio,
+ .set_tdm_slot = rt274_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver rt274_dai[] = {
+ {
+ .name = "rt274-aif1",
+ .id = RT274_AIF1,
+ .playback = {
+ .stream_name = "AIF1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RT274_STEREO_RATES,
+ .formats = RT274_FORMATS,
+ },
+ .capture = {
+ .stream_name = "AIF1 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RT274_STEREO_RATES,
+ .formats = RT274_FORMATS,
+ },
+ .ops = &rt274_aif_dai_ops,
+ .symmetric_rates = 1,
+ },
+};
+
+static const struct snd_soc_codec_driver soc_codec_dev_rt274 = {
+ .probe = rt274_probe,
+ .remove = rt274_remove,
+ .suspend = rt274_suspend,
+ .resume = rt274_resume,
+ .set_bias_level = rt274_set_bias_level,
+ .idle_bias_off = true,
+ .component_driver = {
+ .controls = rt274_snd_controls,
+ .num_controls = ARRAY_SIZE(rt274_snd_controls),
+ .dapm_widgets = rt274_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(rt274_dapm_widgets),
+ .dapm_routes = rt274_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(rt274_dapm_routes),
+ },
+ .set_jack = rt274_mic_detect,
+};
+
+static const struct regmap_config rt274_regmap = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .max_register = 0x05bfffff,
+ .volatile_reg = rt274_volatile_register,
+ .readable_reg = rt274_readable_register,
+ .reg_write = rl6347a_hw_write,
+ .reg_read = rl6347a_hw_read,
+ .cache_type = REGCACHE_RBTREE,
+ .reg_defaults = rt274_reg,
+ .num_reg_defaults = ARRAY_SIZE(rt274_reg),
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id rt274_of_match[] = {
+ {.compatible = "realtek,rt274"},
+ {},
+};
+MODULE_DEVICE_TABLE(of, rt274_of_match);
+#endif
+
+static const struct i2c_device_id rt274_i2c_id[] = {
+ {"rt274", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, rt274_i2c_id);
+
+static const struct acpi_device_id rt274_acpi_match[] = {
+ { "10EC0274", 0 },
+ { "INT34C2", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, rt274_acpi_match);
+
+static int rt274_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct rt274_priv *rt274;
+
+ int ret;
+ unsigned int val;
+
+ rt274 = devm_kzalloc(&i2c->dev, sizeof(*rt274),
+ GFP_KERNEL);
+ if (rt274 == NULL)
+ return -ENOMEM;
+
+ rt274->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt274_regmap);
+ if (IS_ERR(rt274->regmap)) {
+ ret = PTR_ERR(rt274->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ regmap_read(rt274->regmap,
+ RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val);
+ if (val != RT274_VENDOR_ID) {
+ dev_err(&i2c->dev,
+ "Device with ID register %#x is not rt274\n", val);
+ return -ENODEV;
+ }
+
+ rt274->index_cache = devm_kmemdup(&i2c->dev, rt274_index_def,
+ sizeof(rt274_index_def), GFP_KERNEL);
+ if (!rt274->index_cache)
+ return -ENOMEM;
+
+ rt274->index_cache_size = INDEX_CACHE_SIZE;
+ rt274->i2c = i2c;
+ i2c_set_clientdata(i2c, rt274);
+
+ /* reset codec */
+ regmap_write(rt274->regmap, RT274_RESET, 0);
+ regmap_update_bits(rt274->regmap, 0x1a, 0x4000, 0x4000);
+
+ /* Set Pad PDB is floating */
+ regmap_update_bits(rt274->regmap, RT274_PAD_CTRL12, 0x3, 0x0);
+ regmap_write(rt274->regmap, RT274_COEF5b_INDEX, 0x01);
+ regmap_write(rt274->regmap, RT274_COEF5b_COEF, 0x8540);
+ regmap_update_bits(rt274->regmap, 0x6f, 0x0100, 0x0100);
+ /* Combo jack auto detect */
+ regmap_write(rt274->regmap, 0x4a, 0x201b);
+ /* Aux mode off */
+ regmap_update_bits(rt274->regmap, 0x6f, 0x3000, 0x2000);
+ /* HP DC Calibration */
+ regmap_update_bits(rt274->regmap, 0x6f, 0xf, 0x0);
+ /* Set NID=58h.Index 00h [15]= 1b; */
+ regmap_write(rt274->regmap, RT274_COEF58_INDEX, 0x00);
+ regmap_write(rt274->regmap, RT274_COEF58_COEF, 0xb888);
+ msleep(500);
+ regmap_update_bits(rt274->regmap, 0x6f, 0xf, 0xb);
+ regmap_write(rt274->regmap, RT274_COEF58_INDEX, 0x00);
+ regmap_write(rt274->regmap, RT274_COEF58_COEF, 0x3888);
+ /* Set pin widget */
+ regmap_write(rt274->regmap, RT274_SET_PIN_HPO, 0x40);
+ regmap_write(rt274->regmap, RT274_SET_PIN_LOUT3, 0x40);
+ regmap_write(rt274->regmap, RT274_SET_MIC, 0x20);
+ regmap_write(rt274->regmap, RT274_SET_PIN_DMIC1, 0x20);
+
+ regmap_update_bits(rt274->regmap, RT274_I2S_CTRL2, 0xc004, 0x4004);
+ regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL,
+ RT274_GPI2_SEL_MASK, RT274_GPI2_SEL_DMIC_CLK);
+
+ /* jack detection */
+ regmap_write(rt274->regmap, RT274_UNSOLICITED_HP_OUT, 0x81);
+ regmap_write(rt274->regmap, RT274_UNSOLICITED_MIC, 0x82);
+
+ if (rt274->i2c->irq) {
+ ret = request_threaded_irq(rt274->i2c->irq, NULL, rt274_irq,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt274", rt274);
+ if (ret != 0) {
+ dev_err(&i2c->dev,
+ "Failed to reguest IRQ: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt274,
+ rt274_dai, ARRAY_SIZE(rt274_dai));
+
+ return ret;
+}
+
+static int rt274_i2c_remove(struct i2c_client *i2c)
+{
+ struct rt274_priv *rt274 = i2c_get_clientdata(i2c);
+
+ if (i2c->irq)
+ free_irq(i2c->irq, rt274);
+ snd_soc_unregister_codec(&i2c->dev);
+
+ return 0;
+}
+
+
+static struct i2c_driver rt274_i2c_driver = {
+ .driver = {
+ .name = "rt274",
+ .acpi_match_table = ACPI_PTR(rt274_acpi_match),
+#ifdef CONFIG_OF
+ .of_match_table = of_match_ptr(rt274_of_match),
+#endif
+ },
+ .probe = rt274_i2c_probe,
+ .remove = rt274_i2c_remove,
+ .id_table = rt274_i2c_id,
+};
+
+module_i2c_driver(rt274_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC RT274 driver");
+MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt274.h b/sound/soc/codecs/rt274.h
new file mode 100644
index 000000000000..4fd1bcb73dba
--- /dev/null
+++ b/sound/soc/codecs/rt274.h
@@ -0,0 +1,217 @@
+/*
+ * rt274.h -- RT274 ALSA SoC audio driver
+ *
+ * Copyright 2016 Realtek Microelectronics
+ * Author: Bard Liao <bardliao@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __RT274_H__
+#define __RT274_H__
+
+#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D)
+
+#define RT274_AUDIO_FUNCTION_GROUP 0x01
+#define RT274_DAC_OUT0 0x02
+#define RT274_DAC_OUT1 0x03
+#define RT274_ADC_IN2 0x08
+#define RT274_ADC_IN1 0x09
+#define RT274_DIG_CVT 0x0a
+#define RT274_DMIC1 0x12
+#define RT274_DMIC2 0x13
+#define RT274_MIC 0x19
+#define RT274_LINE1 0x1a
+#define RT274_LINE2 0x1b
+#define RT274_LINE3 0x16
+#define RT274_SPDIF 0x1e
+#define RT274_VENDOR_REGISTERS 0x20
+#define RT274_HP_OUT 0x21
+#define RT274_MIXER_IN1 0x22
+#define RT274_MIXER_IN2 0x23
+#define RT274_INLINE_CMD 0x55
+
+#define RT274_SET_PIN_SFT 6
+#define RT274_SET_PIN_ENABLE 0x40
+#define RT274_SET_PIN_DISABLE 0
+#define RT274_SET_EAPD_HIGH 0x2
+#define RT274_SET_EAPD_LOW 0
+
+#define RT274_MUTE_SFT 7
+
+/* Verb commands */
+#define RT274_RESET\
+ VERB_CMD(AC_VERB_SET_CODEC_RESET, RT274_AUDIO_FUNCTION_GROUP, 0)
+#define RT274_GET_PARAM(NID, PARAM) VERB_CMD(AC_VERB_PARAMETERS, NID, PARAM)
+#define RT274_SET_POWER(NID) VERB_CMD(AC_VERB_SET_POWER_STATE, NID, 0)
+#define RT274_SET_AUDIO_POWER RT274_SET_POWER(RT274_AUDIO_FUNCTION_GROUP)
+#define RT274_SET_HPO_POWER RT274_SET_POWER(RT274_HP_OUT)
+#define RT274_SET_DMIC1_POWER RT274_SET_POWER(RT274_DMIC1)
+#define RT274_LOUT_MUX\
+ VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_LINE3, 0)
+#define RT274_HPO_MUX\
+ VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_HP_OUT, 0)
+#define RT274_ADC0_MUX\
+ VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_MIXER_IN1, 0)
+#define RT274_ADC1_MUX\
+ VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_MIXER_IN2, 0)
+#define RT274_SET_MIC\
+ VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_MIC, 0)
+#define RT274_SET_PIN_LOUT3\
+ VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_LINE3, 0)
+#define RT274_SET_PIN_HPO\
+ VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0)
+#define RT274_SET_PIN_DMIC1\
+ VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0)
+#define RT274_SET_PIN_SPDIF\
+ VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_SPDIF, 0)
+#define RT274_SET_PIN_DIG_CVT\
+ VERB_CMD(AC_VERB_SET_DIGI_CONVERT_1, RT274_DIG_CVT, 0)
+#define RT274_SET_AMP_GAIN_HPO\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0)
+#define RT274_SET_AMP_GAIN_ADC_IN1\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0)
+#define RT274_SET_AMP_GAIN_ADC_IN2\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0)
+#define RT274_GET_HP_SENSE\
+ VERB_CMD(AC_VERB_GET_PIN_SENSE, RT274_HP_OUT, 0)
+#define RT274_GET_MIC_SENSE\
+ VERB_CMD(AC_VERB_GET_PIN_SENSE, RT274_MIC, 0)
+#define RT274_SET_DMIC2_DEFAULT\
+ VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT274_DMIC2, 0)
+#define RT274_SET_SPDIF_DEFAULT\
+ VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT274_SPDIF, 0)
+#define RT274_DAC0L_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0xa000)
+#define RT274_DAC0R_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0x9000)
+#define RT274_DAC1L_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0xa000)
+#define RT274_DAC1R_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0x9000)
+#define RT274_ADCL_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0x6000)
+#define RT274_ADCR_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0x5000)
+#define RT274_MIC_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_MIC, 0x7000)
+#define RT274_LOUTL_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_LINE3, 0xa000)
+#define RT274_LOUTR_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_LINE3, 0x9000)
+#define RT274_HPOL_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0xa000)
+#define RT274_HPOR_GAIN\
+ VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0x9000)
+#define RT274_DAC_FORMAT\
+ VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT274_DAC_OUT0, 0)
+#define RT274_ADC_FORMAT\
+ VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT274_ADC_IN1, 0)
+#define RT274_COEF_INDEX\
+ VERB_CMD(AC_VERB_SET_COEF_INDEX, RT274_VENDOR_REGISTERS, 0)
+#define RT274_PROC_COEF\
+ VERB_CMD(AC_VERB_SET_PROC_COEF, RT274_VENDOR_REGISTERS, 0)
+#define RT274_UNSOLICITED_INLINE_CMD\
+ VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_INLINE_CMD, 0)
+#define RT274_UNSOLICITED_HP_OUT\
+ VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_HP_OUT, 0)
+#define RT274_UNSOLICITED_MIC\
+ VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_MIC, 0)
+#define RT274_COEF58_INDEX\
+ VERB_CMD(AC_VERB_SET_COEF_INDEX, 0x58, 0)
+#define RT274_COEF58_COEF\
+ VERB_CMD(AC_VERB_SET_PROC_COEF, 0x58, 0)
+#define RT274_COEF5b_INDEX\
+ VERB_CMD(AC_VERB_SET_COEF_INDEX, 0x5b, 0)
+#define RT274_COEF5b_COEF\
+ VERB_CMD(AC_VERB_SET_PROC_COEF, 0x5b, 0)
+#define RT274_SET_STREAMID_DAC0\
+ VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_DAC_OUT0, 0)
+#define RT274_SET_STREAMID_DAC1\
+ VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_DAC_OUT1, 0)
+#define RT274_SET_STREAMID_ADC1\
+ VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_ADC_IN1, 0)
+#define RT274_SET_STREAMID_ADC2\
+ VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_ADC_IN2, 0)
+
+/* Index registers */
+#define RT274_EAPD_GPIO_IRQ_CTRL 0x10
+#define RT274_PAD_CTRL12 0x35
+#define RT274_I2S_CTRL1 0x63
+#define RT274_I2S_CTRL2 0x64
+#define RT274_MCLK_CTRL 0x71
+#define RT274_CLK_CTRL 0x72
+#define RT274_PLL2_CTRL 0x7b
+
+
+/* EAPD GPIO IRQ control (Index 0x10) */
+#define RT274_IRQ_DIS (0x0 << 13)
+#define RT274_IRQ_EN (0x1 << 13)
+#define RT274_IRQ_CLR (0x1 << 12)
+#define RT274_GPI2_SEL_MASK (0x3 << 7)
+#define RT274_GPI2_SEL_GPIO2 (0x0 << 7)
+#define RT274_GPI2_SEL_I2S (0x1 << 7)
+#define RT274_GPI2_SEL_DMIC_CLK (0x2 << 7)
+#define RT274_GPI2_SEL_CBJ (0x3 << 7)
+
+/* Front I2S_Interface control 1 (Index 0x63) */
+#define RT274_I2S_MODE_MASK (0x1 << 11)
+#define RT274_I2S_MODE_S (0x0 << 11)
+#define RT274_I2S_MODE_M (0x1 << 11)
+#define RT274_TDM_DIS (0x0 << 10)
+#define RT274_TDM_EN (0x1 << 10)
+#define RT274_TDM_CH_NUM (0x1 << 7)
+#define RT274_TDM_2CH (0x0 << 7)
+#define RT274_TDM_4CH (0x1 << 7)
+#define RT274_I2S_FMT_MASK (0x3 << 8)
+#define RT274_I2S_FMT_I2S (0x0 << 8)
+#define RT274_I2S_FMT_LJ (0x1 << 8)
+#define RT274_I2S_FMT_PCMA (0x2 << 8)
+#define RT274_I2S_FMT_PCMB (0x3 << 8)
+
+/* MCLK clock domain control (Index 0x71) */
+#define RT274_MCLK_MODE_MASK (0x1 << 14)
+#define RT274_MCLK_MODE_DIS (0x0 << 14)
+#define RT274_MCLK_MODE_EN (0x1 << 14)
+
+/* Clock control (Index 0x72) */
+#define RT274_CLK_SRC_MASK (0x7 << 3)
+#define RT274_CLK_SRC_MCLK (0x0 << 3)
+#define RT274_CLK_SRC_PLL2 (0x3 << 3)
+
+/* PLL2 control (Index 0x7b) */
+#define RT274_PLL2_SRC_MASK (0x1 << 13)
+#define RT274_PLL2_SRC_MCLK (0x0 << 13)
+#define RT274_PLL2_SRC_BCLK (0x1 << 13)
+
+/* HP-OUT (0x21) */
+#define RT274_M_HP_MUX_SFT 14
+#define RT274_HP_SEL_MASK 0x1
+#define RT274_HP_SEL_SFT 0
+#define RT274_HP_SEL_F 0
+#define RT274_HP_SEL_S 1
+
+/* ADC (0x22) (0x23) */
+#define RT274_ADC_SEL_MASK 0x7
+#define RT274_ADC_SEL_SFT 0
+#define RT274_ADC_SEL_MIC 0
+#define RT274_ADC_SEL_LINE1 1
+#define RT274_ADC_SEL_LINE2 2
+#define RT274_ADC_SEL_DMIC 3
+
+#define RT274_SCLK_S_MCLK 0
+#define RT274_SCLK_S_PLL1 1
+#define RT274_SCLK_S_PLL2 2
+
+#define RT274_PLL2_S_MCLK 0
+#define RT274_PLL2_S_BCLK 1
+
+enum {
+ RT274_AIF1,
+ RT274_AIFS,
+};
+
+#endif /* __RT274_H__ */
+
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 7899a2cdeb42..af6325c78292 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -1046,7 +1046,7 @@ static struct snd_soc_dai_driver rt286_dai[] = {
};
-static struct snd_soc_codec_driver soc_codec_dev_rt286 = {
+static const struct snd_soc_codec_driver soc_codec_dev_rt286 = {
.probe = rt286_probe,
.remove = rt286_remove,
.suspend = rt286_suspend,
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
index d9e96e65e1c4..ce963768449f 100644
--- a/sound/soc/codecs/rt298.c
+++ b/sound/soc/codecs/rt298.c
@@ -1113,7 +1113,7 @@ static struct snd_soc_dai_driver rt298_dai[] = {
};
-static struct snd_soc_codec_driver soc_codec_dev_rt298 = {
+static const struct snd_soc_codec_driver soc_codec_dev_rt298 = {
.probe = rt298_probe,
.remove = rt298_remove,
.suspend = rt298_suspend,
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
index 7ed62e8c80b4..ed6e5373916c 100644
--- a/sound/soc/codecs/rt5514-spi.c
+++ b/sound/soc/codecs/rt5514-spi.c
@@ -43,9 +43,7 @@ struct rt5514_dsp {
struct mutex dma_lock;
struct snd_pcm_substream *substream;
unsigned int buf_base, buf_limit, buf_rp;
- size_t buf_size;
- size_t dma_offset;
- size_t dsp_offset;
+ size_t buf_size, get_size, dma_offset;
};
static const struct snd_pcm_hardware rt5514_spi_pcm_hardware = {
@@ -80,6 +78,8 @@ static void rt5514_spi_copy_work(struct work_struct *work)
container_of(work, struct rt5514_dsp, copy_work.work);
struct snd_pcm_runtime *runtime;
size_t period_bytes, truncated_bytes = 0;
+ unsigned int cur_wp, remain_data;
+ u8 buf[8];
mutex_lock(&rt5514_dsp->dma_lock);
if (!rt5514_dsp->substream) {
@@ -90,8 +90,24 @@ static void rt5514_spi_copy_work(struct work_struct *work)
runtime = rt5514_dsp->substream->runtime;
period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream);
- if (rt5514_dsp->buf_size - rt5514_dsp->dsp_offset < period_bytes)
- period_bytes = rt5514_dsp->buf_size - rt5514_dsp->dsp_offset;
+ if (rt5514_dsp->get_size >= rt5514_dsp->buf_size) {
+ rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf,
+ sizeof(buf));
+ cur_wp = buf[0] | buf[1] << 8 | buf[2] << 16 |
+ buf[3] << 24;
+
+ if (cur_wp >= rt5514_dsp->buf_rp)
+ remain_data = (cur_wp - rt5514_dsp->buf_rp);
+ else
+ remain_data =
+ (rt5514_dsp->buf_limit - rt5514_dsp->buf_rp) +
+ (cur_wp - rt5514_dsp->buf_base);
+
+ if (remain_data < period_bytes) {
+ schedule_delayed_work(&rt5514_dsp->copy_work, 5);
+ goto done;
+ }
+ }
if (rt5514_dsp->buf_rp + period_bytes <= rt5514_dsp->buf_limit) {
rt5514_spi_burst_read(rt5514_dsp->buf_rp,
@@ -112,24 +128,62 @@ static void rt5514_spi_copy_work(struct work_struct *work)
runtime->dma_area + rt5514_dsp->dma_offset +
truncated_bytes, period_bytes - truncated_bytes);
- rt5514_dsp->buf_rp = rt5514_dsp->buf_base +
- period_bytes - truncated_bytes;
+ rt5514_dsp->buf_rp = rt5514_dsp->buf_base + period_bytes -
+ truncated_bytes;
}
+ rt5514_dsp->get_size += period_bytes;
rt5514_dsp->dma_offset += period_bytes;
if (rt5514_dsp->dma_offset >= runtime->dma_bytes)
rt5514_dsp->dma_offset = 0;
- rt5514_dsp->dsp_offset += period_bytes;
-
snd_pcm_period_elapsed(rt5514_dsp->substream);
- if (rt5514_dsp->dsp_offset < rt5514_dsp->buf_size)
- schedule_delayed_work(&rt5514_dsp->copy_work, 5);
+ schedule_delayed_work(&rt5514_dsp->copy_work, 5);
+
done:
mutex_unlock(&rt5514_dsp->dma_lock);
}
+static irqreturn_t rt5514_spi_irq(int irq, void *data)
+{
+ struct rt5514_dsp *rt5514_dsp = data;
+ u8 buf[8];
+
+ rt5514_dsp->get_size = 0;
+
+ /**
+ * The address area x1800XXXX is the register address, and it cannot
+ * support spi burst read perfectly. So we use the spi burst read
+ * individually to make sure the data correctly.
+ */
+ rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf,
+ sizeof(buf));
+ rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 |
+ buf[3] << 24;