aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/atmel/Kconfig2
-rw-r--r--sound/atmel/ac97c.c355
-rw-r--r--sound/core/control.c5
-rw-r--r--sound/core/info.c74
-rw-r--r--sound/core/jack.c71
-rw-r--r--sound/core/oss/mixer_oss.c5
-rw-r--r--sound/core/oss/pcm_oss.c5
-rw-r--r--sound/core/pcm.c3
-rw-r--r--sound/core/pcm_native.c63
-rw-r--r--sound/core/rawmidi.c5
-rw-r--r--sound/core/seq/seq_clientmgr.c6
-rw-r--r--sound/core/sound.c73
-rw-r--r--sound/core/timer.c6
-rw-r--r--sound/drivers/opl4/opl4_proc.c83
-rw-r--r--sound/drivers/pcsp/pcsp.h2
-rw-r--r--sound/drivers/pcsp/pcsp_input.c4
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c12
-rw-r--r--sound/i2c/i2c.c18
-rw-r--r--sound/isa/Kconfig16
-rw-r--r--sound/isa/es1688/es1688.c225
-rw-r--r--sound/isa/es1688/es1688_lib.c47
-rw-r--r--sound/isa/gus/gus_mem_proc.c48
-rw-r--r--sound/isa/gus/gusextreme.c26
-rw-r--r--sound/isa/sb/Makefile2
-rw-r--r--sound/isa/sb/es968.c248
-rw-r--r--sound/oss/dmasound/dmasound_paula.c51
-rw-r--r--sound/pci/Kconfig32
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/asihpi/Makefile5
-rw-r--r--sound/pci/asihpi/asihpi.c3002
-rw-r--r--sound/pci/asihpi/hpi.h2001
-rw-r--r--sound/pci/asihpi/hpi6000.c1840
-rw-r--r--sound/pci/asihpi/hpi6000.h70
-rw-r--r--sound/pci/asihpi/hpi6205.c2331
-rw-r--r--sound/pci/asihpi/hpi6205.h93
-rw-r--r--sound/pci/asihpi/hpi_internal.h1641
-rw-r--r--sound/pci/asihpi/hpicmn.c643
-rw-r--r--sound/pci/asihpi/hpicmn.h64
-rw-r--r--sound/pci/asihpi/hpidebug.c225
-rw-r--r--sound/pci/asihpi/hpidebug.h385
-rw-r--r--sound/pci/asihpi/hpidspcd.c172
-rw-r--r--sound/pci/asihpi/hpidspcd.h104
-rw-r--r--sound/pci/asihpi/hpifunc.c3864
-rw-r--r--sound/pci/asihpi/hpimsginit.c130
-rw-r--r--sound/pci/asihpi/hpimsginit.h40
-rw-r--r--sound/pci/asihpi/hpimsgx.c907
-rw-r--r--sound/pci/asihpi/hpimsgx.h36
-rw-r--r--sound/pci/asihpi/hpioctl.c484
-rw-r--r--sound/pci/asihpi/hpioctl.h38
-rw-r--r--sound/pci/asihpi/hpios.c114
-rw-r--r--sound/pci/asihpi/hpios.h178
-rw-r--r--sound/pci/asihpi/hpipcida.h37
-rw-r--r--sound/pci/cs4281.c40
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c19
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c2
-rw-r--r--sound/pci/emu10k1/emuproc.c51
-rw-r--r--sound/pci/es1968.c129
-rw-r--r--sound/pci/hda/Kconfig1
-rw-r--r--sound/pci/hda/hda_codec.c76
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_intel.c109
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/patch_analog.c21
-rw-r--r--sound/pci/hda/patch_conexant.c157
-rw-r--r--sound/pci/hda/patch_hdmi.c10
-rw-r--r--sound/pci/hda/patch_intelhdmi.c21
-rw-r--r--sound/pci/hda/patch_realtek.c238
-rw-r--r--sound/pci/ice1712/aureon.c89
-rw-r--r--sound/pci/maestro3.c139
-rw-r--r--sound/pci/mixart/mixart.c79
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c12
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.h1
-rw-r--r--sound/pcmcia/vx/vxpocket.c10
-rw-r--r--sound/pcmcia/vx/vxpocket.h1
-rw-r--r--sound/ppc/tumbler.c12
-rw-r--r--sound/soc/atmel/atmel-pcm.c14
-rw-r--r--sound/soc/blackfin/Kconfig9
-rw-r--r--sound/soc/blackfin/Makefile4
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c (renamed from sound/soc/blackfin/bf5xx-ad1938.c)66
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h28
-rw-r--r--sound/soc/codecs/Kconfig16
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ad1836.c2
-rw-r--r--sound/soc/codecs/ad1938.c522
-rw-r--r--sound/soc/codecs/ad1938.h100
-rw-r--r--sound/soc/codecs/ad193x.c547
-rw-r--r--sound/soc/codecs/ad193x.h81
-rw-r--r--sound/soc/codecs/ak4104.c2
-rw-r--r--sound/soc/codecs/ak4535.c11
-rw-r--r--sound/soc/codecs/ak4642.c177
-rw-r--r--sound/soc/codecs/ak4671.c2
-rw-r--r--sound/soc/codecs/cq93vc.c299
-rw-r--r--sound/soc/codecs/cq93vc.h29
-rw-r--r--sound/soc/codecs/cs4270.c20
-rw-r--r--sound/soc/codecs/cx20442.c2
-rw-r--r--sound/soc/codecs/da7210.c157
-rw-r--r--sound/soc/codecs/ssm2602.c17
-rw-r--r--sound/soc/codecs/stac9766.c5
-rw-r--r--sound/soc/codecs/tlv320aic23.c1
-rw-r--r--sound/soc/codecs/tlv320aic26.c14
-rw-r--r--sound/soc/codecs/tlv320aic3x.c118
-rw-r--r--sound/soc/codecs/tlv320dac33.c543
-rw-r--r--sound/soc/codecs/tpa6130a2.c103
-rw-r--r--sound/soc/codecs/twl4030.c203
-rw-r--r--sound/soc/codecs/twl6040.c1246
-rw-r--r--sound/soc/codecs/twl6040.h141
-rw-r--r--sound/soc/codecs/uda134x.c29
-rw-r--r--sound/soc/codecs/uda1380.c5
-rw-r--r--sound/soc/codecs/wm8350.c103
-rw-r--r--sound/soc/codecs/wm8350.h3
-rw-r--r--sound/soc/codecs/wm8400.c16
-rw-r--r--sound/soc/codecs/wm8510.c2
-rw-r--r--sound/soc/codecs/wm8523.c10
-rw-r--r--sound/soc/codecs/wm8580.c4
-rw-r--r--sound/soc/codecs/wm8711.c8
-rw-r--r--sound/soc/codecs/wm8728.c2
-rw-r--r--sound/soc/codecs/wm8731.c66
-rw-r--r--sound/soc/codecs/wm8750.c347
-rw-r--r--sound/soc/codecs/wm8753.c8
-rw-r--r--sound/soc/codecs/wm8776.c6
-rw-r--r--sound/soc/codecs/wm8900.c10
-rw-r--r--sound/soc/codecs/wm8903.c217
-rw-r--r--sound/soc/codecs/wm8903.h221
-rw-r--r--sound/soc/codecs/wm8904.c59
-rw-r--r--sound/soc/codecs/wm8904.h97
-rw-r--r--sound/soc/codecs/wm8940.c5
-rw-r--r--sound/soc/codecs/wm8955.c16
-rw-r--r--sound/soc/codecs/wm8960.c215
-rw-r--r--sound/soc/codecs/wm8960.h11
-rw-r--r--sound/soc/codecs/wm8961.c6
-rw-r--r--sound/soc/codecs/wm8971.c12
-rw-r--r--sound/soc/codecs/wm8974.c6
-rw-r--r--sound/soc/codecs/wm8978.c12
-rw-r--r--sound/soc/codecs/wm8988.c8
-rw-r--r--sound/soc/codecs/wm8990.c8
-rw-r--r--sound/soc/codecs/wm8993.c24
-rw-r--r--sound/soc/codecs/wm8994.c264
-rw-r--r--sound/soc/codecs/wm8994.h8
-rw-r--r--sound/soc/codecs/wm9081.c18
-rw-r--r--sound/soc/codecs/wm9090.c773
-rw-r--r--sound/soc/codecs/wm9090.h715
-rw-r--r--sound/soc/codecs/wm9712.c3
-rw-r--r--sound/soc/codecs/wm9713.c16
-rw-r--r--sound/soc/codecs/wm_hubs.c18
-rw-r--r--sound/soc/davinci/Kconfig27
-rw-r--r--sound/soc/davinci/Makefile2
-rw-r--r--sound/soc/davinci/davinci-evm.c61
-rw-r--r--sound/soc/davinci/davinci-vcif.c274
-rw-r--r--sound/soc/davinci/davinci-vcif.h28
-rw-r--r--sound/soc/imx/Kconfig8
-rw-r--r--sound/soc/imx/Makefile3
-rw-r--r--sound/soc/imx/wm1133-ev1.c308
-rw-r--r--sound/soc/omap/Kconfig19
-rw-r--r--sound/soc/omap/Makefile4
-rw-r--r--sound/soc/omap/mcpdm.c548
-rw-r--r--sound/soc/omap/omap-mcbsp.c66
-rw-r--r--sound/soc/omap/omap3pandora.c2
-rw-r--r--sound/soc/omap/rx51.c294
-rw-r--r--sound/soc/omap/sdp4430.c233
-rw-r--r--sound/soc/omap/zoom2.c3
-rw-r--r--sound/soc/pxa/Kconfig9
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/pxa-ssp.c135
-rw-r--r--sound/soc/pxa/spitz.c43
-rw-r--r--sound/soc/pxa/z2.c246
-rw-r--r--sound/soc/s3c24xx/Kconfig12
-rw-r--r--sound/soc/s3c24xx/Makefile2
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c7
-rw-r--r--sound/soc/s3c24xx/neo1973_gta02_wm8753.c8
-rw-r--r--sound/soc/s3c24xx/regs-i2s-v2.h115
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c205
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.h15
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c77
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.h6
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s-v4.c209
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c69
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h18
-rw-r--r--sound/soc/s3c24xx/smdk64xx_wm8580.c6
-rw-r--r--sound/soc/sh/Kconfig3
-rw-r--r--sound/soc/sh/fsi-ak4642.c14
-rw-r--r--sound/soc/sh/fsi.c191
-rw-r--r--sound/soc/soc-cache.c134
-rw-r--r--sound/soc/soc-core.c255
-rw-r--r--sound/soc/soc-dapm.c217
-rw-r--r--sound/soc/soc-jack.c43
-rw-r--r--sound/usb/Kconfig4
-rw-r--r--sound/usb/Makefile26
-rw-r--r--sound/usb/caiaq/control.c99
-rw-r--r--sound/usb/caiaq/device.c8
-rw-r--r--sound/usb/caiaq/device.h24
-rw-r--r--sound/usb/caiaq/input.c163
-rw-r--r--sound/usb/card.c652
-rw-r--r--sound/usb/card.h105
-rw-r--r--sound/usb/debug.h15
-rw-r--r--sound/usb/endpoint.c362
-rw-r--r--sound/usb/endpoint.h11
-rw-r--r--sound/usb/format.c432
-rw-r--r--sound/usb/format.h8
-rw-r--r--sound/usb/helper.c113
-rw-r--r--sound/usb/helper.h32
-rw-r--r--sound/usb/midi.c (renamed from sound/usb/usbmidi.c)3
-rw-r--r--sound/usb/midi.h48
-rw-r--r--sound/usb/misc/Makefile2
-rw-r--r--sound/usb/misc/ua101.c (renamed from sound/usb/ua101.c)3
-rw-r--r--sound/usb/mixer.c (renamed from sound/usb/usbmixer.c)933
-rw-r--r--sound/usb/mixer.h55
-rw-r--r--sound/usb/mixer_maps.c (renamed from sound/usb/usbmixer_maps.c)4
-rw-r--r--sound/usb/mixer_quirks.c412
-rw-r--r--sound/usb/mixer_quirks.h13
-rw-r--r--sound/usb/pcm.c935
-rw-r--r--sound/usb/pcm.h14
-rw-r--r--sound/usb/proc.c168
-rw-r--r--sound/usb/proc.h8
-rw-r--r--sound/usb/quirks-table.h (renamed from sound/usb/usbquirks.h)68
-rw-r--r--sound/usb/quirks.c594
-rw-r--r--sound/usb/quirks.h23
-rw-r--r--sound/usb/urb.c995
-rw-r--r--sound/usb/urb.h21
-rw-r--r--sound/usb/usbaudio.c4050
-rw-r--r--sound/usb/usbaudio.h93
-rw-r--r--sound/usb/usx2y/us122l.c1
-rw-r--r--sound/usb/usx2y/usbusx2y.h1
222 files changed, 34897 insertions, 8476 deletions
diff --git a/sound/atmel/Kconfig b/sound/atmel/Kconfig
index 6c228a91940d..94de43a096f1 100644
--- a/sound/atmel/Kconfig
+++ b/sound/atmel/Kconfig
@@ -12,7 +12,7 @@ config SND_ATMEL_AC97C
12 tristate "Atmel AC97 Controller (AC97C) driver" 12 tristate "Atmel AC97 Controller (AC97C) driver"
13 select SND_PCM 13 select SND_PCM
14 select SND_AC97_CODEC 14 select SND_AC97_CODEC
15 depends on DW_DMAC && AVR32 15 depends on (DW_DMAC && AVR32) || ARCH_AT91
16 help 16 help
17 ALSA sound driver for the Atmel AC97 controller. 17 ALSA sound driver for the Atmel AC97 controller.
18 18
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index 0c0f8771656a..428121a7e705 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/dmaengine.h> 14#include <linux/dmaengine.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <linux/atmel_pdc.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/interrupt.h> 18#include <linux/interrupt.h>
18#include <linux/module.h> 19#include <linux/module.h>
@@ -31,6 +32,10 @@
31 32
32#include <linux/dw_dmac.h> 33#include <linux/dw_dmac.h>
33 34
35#include <mach/cpu.h>
36#include <mach/hardware.h>
37#include <mach/gpio.h>
38
34#include "ac97c.h" 39#include "ac97c.h"
35 40
36enum { 41enum {
@@ -63,6 +68,7 @@ struct atmel_ac97c {
63 u64 cur_format; 68 u64 cur_format;
64 unsigned int cur_rate; 69 unsigned int cur_rate;
65 unsigned long flags; 70 unsigned long flags;
71 int playback_period, capture_period;
66 /* Serialize access to opened variable */ 72 /* Serialize access to opened variable */
67 spinlock_t lock; 73 spinlock_t lock;
68 void __iomem *regs; 74 void __iomem *regs;
@@ -242,10 +248,12 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream,
242 if (retval < 0) 248 if (retval < 0)
243 return retval; 249 return retval;
244 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ 250 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
245 if (retval == 1) 251 if (cpu_is_at32ap7000()) {
246 if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) 252 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
247 dw_dma_cyclic_free(chip->dma.tx_chan); 253 if (retval == 1)
248 254 if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
255 dw_dma_cyclic_free(chip->dma.tx_chan);
256 }
249 /* Set restrictions to params. */ 257 /* Set restrictions to params. */
250 mutex_lock(&opened_mutex); 258 mutex_lock(&opened_mutex);
251 chip->cur_rate = params_rate(hw_params); 259 chip->cur_rate = params_rate(hw_params);
@@ -266,9 +274,14 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
266 if (retval < 0) 274 if (retval < 0)
267 return retval; 275 return retval;
268 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ 276 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
269 if (retval == 1) 277 if (cpu_is_at32ap7000()) {
270 if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) 278 if (retval < 0)
271 dw_dma_cyclic_free(chip->dma.rx_chan); 279 return retval;
280 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
281 if (retval == 1)
282 if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
283 dw_dma_cyclic_free(chip->dma.rx_chan);
284 }
272 285
273 /* Set restrictions to params. */ 286 /* Set restrictions to params. */
274 mutex_lock(&opened_mutex); 287 mutex_lock(&opened_mutex);
@@ -282,16 +295,20 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
282static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) 295static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream)
283{ 296{
284 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 297 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
285 if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) 298 if (cpu_is_at32ap7000()) {
286 dw_dma_cyclic_free(chip->dma.tx_chan); 299 if (test_and_clear_bit(DMA_TX_READY, &chip->flags))
300 dw_dma_cyclic_free(chip->dma.tx_chan);
301 }
287 return snd_pcm_lib_free_pages(substream); 302 return snd_pcm_lib_free_pages(substream);
288} 303}
289 304
290static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) 305static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream)
291{ 306{
292 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 307 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
293 if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) 308 if (cpu_is_at32ap7000()) {
294 dw_dma_cyclic_free(chip->dma.rx_chan); 309 if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
310 dw_dma_cyclic_free(chip->dma.rx_chan);
311 }
295 return snd_pcm_lib_free_pages(substream); 312 return snd_pcm_lib_free_pages(substream);
296} 313}
297 314
@@ -299,9 +316,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
299{ 316{
300 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 317 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
301 struct snd_pcm_runtime *runtime = substream->runtime; 318 struct snd_pcm_runtime *runtime = substream->runtime;
319 int block_size = frames_to_bytes(runtime, runtime->period_size);
302 unsigned long word = ac97c_readl(chip, OCA); 320 unsigned long word = ac97c_readl(chip, OCA);
303 int retval; 321 int retval;
304 322
323 chip->playback_period = 0;
305 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); 324 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
306 325
307 /* assign channels to AC97C channel A */ 326 /* assign channels to AC97C channel A */
@@ -320,11 +339,16 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
320 ac97c_writel(chip, OCA, word); 339 ac97c_writel(chip, OCA, word);
321 340
322 /* configure sample format and size */ 341 /* configure sample format and size */
323 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; 342 word = ac97c_readl(chip, CAMR);
343 if (chip->opened <= 1)
344 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
345 else
346 word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
324 347
325 switch (runtime->format) { 348 switch (runtime->format) {
326 case SNDRV_PCM_FORMAT_S16_LE: 349 case SNDRV_PCM_FORMAT_S16_LE:
327 word |= AC97C_CMR_CEM_LITTLE; 350 if (cpu_is_at32ap7000())
351 word |= AC97C_CMR_CEM_LITTLE;
328 break; 352 break;
329 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ 353 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
330 word &= ~(AC97C_CMR_CEM_LITTLE); 354 word &= ~(AC97C_CMR_CEM_LITTLE);
@@ -363,9 +387,18 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
363 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", 387 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
364 runtime->rate); 388 runtime->rate);
365 389
366 if (!test_bit(DMA_TX_READY, &chip->flags)) 390 if (cpu_is_at32ap7000()) {
367 retval = atmel_ac97c_prepare_dma(chip, substream, 391 if (!test_bit(DMA_TX_READY, &chip->flags))
368 DMA_TO_DEVICE); 392 retval = atmel_ac97c_prepare_dma(chip, substream,
393 DMA_TO_DEVICE);
394 } else {
395 /* Initialize and start the PDC */
396 writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR);
397 writel(block_size / 2, chip->regs + ATMEL_PDC_TCR);
398 writel(runtime->dma_addr + block_size,
399 chip->regs + ATMEL_PDC_TNPR);
400 writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR);
401 }
369 402
370 return retval; 403 return retval;
371} 404}
@@ -374,9 +407,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
374{ 407{
375 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 408 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
376 struct snd_pcm_runtime *runtime = substream->runtime; 409 struct snd_pcm_runtime *runtime = substream->runtime;
410 int block_size = frames_to_bytes(runtime, runtime->period_size);
377 unsigned long word = ac97c_readl(chip, ICA); 411 unsigned long word = ac97c_readl(chip, ICA);
378 int retval; 412 int retval;
379 413
414 chip->capture_period = 0;
380 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); 415 word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
381 416
382 /* assign channels to AC97C channel A */ 417 /* assign channels to AC97C channel A */
@@ -395,11 +430,16 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
395 ac97c_writel(chip, ICA, word); 430 ac97c_writel(chip, ICA, word);
396 431
397 /* configure sample format and size */ 432 /* configure sample format and size */
398 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; 433 word = ac97c_readl(chip, CAMR);
434 if (chip->opened <= 1)
435 word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
436 else
437 word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16;
399 438
400 switch (runtime->format) { 439 switch (runtime->format) {
401 case SNDRV_PCM_FORMAT_S16_LE: 440 case SNDRV_PCM_FORMAT_S16_LE:
402 word |= AC97C_CMR_CEM_LITTLE; 441 if (cpu_is_at32ap7000())
442 word |= AC97C_CMR_CEM_LITTLE;
403 break; 443 break;
404 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ 444 case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
405 word &= ~(AC97C_CMR_CEM_LITTLE); 445 word &= ~(AC97C_CMR_CEM_LITTLE);
@@ -438,9 +478,18 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
438 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", 478 dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n",
439 runtime->rate); 479 runtime->rate);
440 480
441 if (!test_bit(DMA_RX_READY, &chip->flags)) 481 if (cpu_is_at32ap7000()) {
442 retval = atmel_ac97c_prepare_dma(chip, substream, 482 if (!test_bit(DMA_RX_READY, &chip->flags))
443 DMA_FROM_DEVICE); 483 retval = atmel_ac97c_prepare_dma(chip, substream,
484 DMA_FROM_DEVICE);
485 } else {
486 /* Initialize and start the PDC */
487 writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR);
488 writel(block_size / 2, chip->regs + ATMEL_PDC_RCR);
489 writel(runtime->dma_addr + block_size,
490 chip->regs + ATMEL_PDC_RNPR);
491 writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR);
492 }
444 493
445 return retval; 494 return retval;
446} 495}
@@ -449,7 +498,7 @@ static int
449atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) 498atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
450{ 499{
451 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 500 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
452 unsigned long camr; 501 unsigned long camr, ptcr = 0;
453 int retval = 0; 502 int retval = 0;
454 503
455 camr = ac97c_readl(chip, CAMR); 504 camr = ac97c_readl(chip, CAMR);
@@ -458,15 +507,22 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
458 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ 507 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
459 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ 508 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
460 case SNDRV_PCM_TRIGGER_START: 509 case SNDRV_PCM_TRIGGER_START:
461 retval = dw_dma_cyclic_start(chip->dma.tx_chan); 510 if (cpu_is_at32ap7000()) {
462 if (retval) 511 retval = dw_dma_cyclic_start(chip->dma.tx_chan);
463 goto out; 512 if (retval)
464 camr |= AC97C_CMR_CENA; 513 goto out;
514 } else {
515 ptcr = ATMEL_PDC_TXTEN;
516 }
517 camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX;
465 break; 518 break;
466 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ 519 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
467 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ 520 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
468 case SNDRV_PCM_TRIGGER_STOP: 521 case SNDRV_PCM_TRIGGER_STOP:
469 dw_dma_cyclic_stop(chip->dma.tx_chan); 522 if (cpu_is_at32ap7000())
523 dw_dma_cyclic_stop(chip->dma.tx_chan);
524 else
525 ptcr |= ATMEL_PDC_TXTDIS;
470 if (chip->opened <= 1) 526 if (chip->opened <= 1)
471 camr &= ~AC97C_CMR_CENA; 527 camr &= ~AC97C_CMR_CENA;
472 break; 528 break;
@@ -476,6 +532,8 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd)
476 } 532 }
477 533
478 ac97c_writel(chip, CAMR, camr); 534 ac97c_writel(chip, CAMR, camr);
535 if (!cpu_is_at32ap7000())
536 writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
479out: 537out:
480 return retval; 538 return retval;
481} 539}
@@ -484,24 +542,32 @@ static int
484atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) 542atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
485{ 543{
486 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); 544 struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
487 unsigned long camr; 545 unsigned long camr, ptcr = 0;
488 int retval = 0; 546 int retval = 0;
489 547
490 camr = ac97c_readl(chip, CAMR); 548 camr = ac97c_readl(chip, CAMR);
549 ptcr = readl(chip->regs + ATMEL_PDC_PTSR);
491 550
492 switch (cmd) { 551 switch (cmd) {
493 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ 552 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
494 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ 553 case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
495 case SNDRV_PCM_TRIGGER_START: 554 case SNDRV_PCM_TRIGGER_START:
496 retval = dw_dma_cyclic_start(chip->dma.rx_chan); 555 if (cpu_is_at32ap7000()) {
497 if (retval) 556 retval = dw_dma_cyclic_start(chip->dma.rx_chan);
498 goto out; 557 if (retval)
499 camr |= AC97C_CMR_CENA; 558 goto out;
559 } else {
560 ptcr = ATMEL_PDC_RXTEN;
561 }
562 camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX;
500 break; 563 break;
501 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ 564 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
502 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ 565 case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
503 case SNDRV_PCM_TRIGGER_STOP: 566 case SNDRV_PCM_TRIGGER_STOP:
504 dw_dma_cyclic_stop(chip->dma.rx_chan); 567 if (cpu_is_at32ap7000())
568 dw_dma_cyclic_stop(chip->dma.rx_chan);
569 else
570 ptcr |= (ATMEL_PDC_RXTDIS);
505 if (chip->opened <= 1) 571 if (chip->opened <= 1)
506 camr &= ~AC97C_CMR_CENA; 572 camr &= ~AC97C_CMR_CENA;
507 break; 573 break;
@@ -511,6 +577,8 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd)
511 } 577 }
512 578
513 ac97c_writel(chip, CAMR, camr); 579 ac97c_writel(chip, CAMR, camr);
580 if (!cpu_is_at32ap7000())
581 writel(ptcr, chip->regs + ATMEL_PDC_PTCR);
514out: 582out:
515 return retval; 583 return retval;
516} 584}
@@ -523,7 +591,10 @@ atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream)
523 snd_pcm_uframes_t frames; 591 snd_pcm_uframes_t frames;
524 unsigned long bytes; 592 unsigned long bytes;
525 593
526 bytes = dw_dma_get_src_addr(chip->dma.tx_chan); 594 if (cpu_is_at32ap7000())
595 bytes = dw_dma_get_src_addr(chip->dma.tx_chan);
596 else
597 bytes = readl(chip->regs + ATMEL_PDC_TPR);
527 bytes -= runtime->dma_addr; 598 bytes -= runtime->dma_addr;
528 599
529 frames = bytes_to_frames(runtime, bytes); 600 frames = bytes_to_frames(runtime, bytes);
@@ -540,7 +611,10 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
540 snd_pcm_uframes_t frames; 611 snd_pcm_uframes_t frames;
541 unsigned long bytes; 612 unsigned long bytes;
542 613
543 bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); 614 if (cpu_is_at32ap7000())
615 bytes = dw_dma_get_dst_addr(chip->dma.rx_chan);
616 else
617 bytes = readl(chip->regs + ATMEL_PDC_RPR);
544 bytes -= runtime->dma_addr; 618 bytes -= runtime->dma_addr;
545 619
546 frames = bytes_to_frames(runtime, bytes); 620 frames = bytes_to_frames(runtime, bytes);
@@ -578,8 +652,11 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
578 u32 sr = ac97c_readl(chip, SR); 652 u32 sr = ac97c_readl(chip, SR);
579 u32 casr = ac97c_readl(chip, CASR); 653 u32 casr = ac97c_readl(chip, CASR);
580 u32 cosr = ac97c_readl(chip, COSR); 654 u32 cosr = ac97c_readl(chip, COSR);
655 u32 camr = ac97c_readl(chip, CAMR);
581 656
582 if (sr & AC97C_SR_CAEVT) { 657 if (sr & AC97C_SR_CAEVT) {
658 struct snd_pcm_runtime *runtime;
659 int offset, next_period, block_size;
583 dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", 660 dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
584 casr & AC97C_CSR_OVRUN ? " OVRUN" : "", 661 casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
585 casr & AC97C_CSR_RXRDY ? " RXRDY" : "", 662 casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
@@ -587,6 +664,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
587 casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", 664 casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
588 casr & AC97C_CSR_TXRDY ? " TXRDY" : "", 665 casr & AC97C_CSR_TXRDY ? " TXRDY" : "",
589 !casr ? " NONE" : ""); 666 !casr ? " NONE" : "");
667 if (!cpu_is_at32ap7000()) {
668 if ((casr & camr) & AC97C_CSR_ENDTX) {
669 runtime = chip->playback_substream->runtime;
670 block_size = frames_to_bytes(runtime,
671 runtime->period_size);
672 chip->playback_period++;
673
674 if (chip->playback_period == runtime->periods)
675 chip->playback_period = 0;
676 next_period = chip->playback_period + 1;
677 if (next_period == runtime->periods)
678 next_period = 0;
679
680 offset = block_size * next_period;
681
682 writel(runtime->dma_addr + offset,
683 chip->regs + ATMEL_PDC_TNPR);
684 writel(block_size / 2,
685 chip->regs + ATMEL_PDC_TNCR);
686
687 snd_pcm_period_elapsed(
688 chip->playback_substream);
689 }
690 if ((casr & camr) & AC97C_CSR_ENDRX) {
691 runtime = chip->capture_substream->runtime;
692 block_size = frames_to_bytes(runtime,
693 runtime->period_size);
694 chip->capture_period++;
695
696 if (chip->capture_period == runtime->periods)
697 chip->capture_period = 0;
698 next_period = chip->capture_period + 1;
699 if (next_period == runtime->periods)
700 next_period = 0;
701
702 offset = block_size * next_period;
703
704 writel(runtime->dma_addr + offset,
705 chip->regs + ATMEL_PDC_RNPR);
706 writel(block_size / 2,
707 chip->regs + ATMEL_PDC_RNCR);
708 snd_pcm_period_elapsed(chip->capture_substream);
709 }
710 }
590 retval = IRQ_HANDLED; 711 retval = IRQ_HANDLED;
591 } 712 }
592 713
@@ -608,15 +729,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
608 return retval; 729 return retval;
609} 730}
610 731
732static struct ac97_pcm at91_ac97_pcm_defs[] __devinitdata = {
733 /* Playback */
734 {
735 .exclusive = 1,
736 .r = { {
737 .slots = ((1 << AC97_SLOT_PCM_LEFT)
738 | (1 << AC97_SLOT_PCM_RIGHT)),
739 } },
740 },
741 /* PCM in */
742 {
743 .stream = 1,
744 .exclusive = 1,
745 .r = { {
746 .slots = ((1 << AC97_SLOT_PCM_LEFT)
747 | (1 << AC97_SLOT_PCM_RIGHT)),
748 } }
749 },
750 /* Mic in */
751 {
752 .stream = 1,
753 .exclusive = 1,
754 .r = { {
755 .slots = (1<<AC97_SLOT_MIC),
756 } }
757 },
758};
759
611static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip) 760static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
612{ 761{
613 struct snd_pcm *pcm; 762 struct snd_pcm *pcm;
614 struct snd_pcm_hardware hw = atmel_ac97c_hw; 763 struct snd_pcm_hardware hw = atmel_ac97c_hw;
615 int capture, playback, retval; 764 int capture, playback, retval, err;
616 765
617 capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 766 capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
618 playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 767 playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
619 768
769 if (!cpu_is_at32ap7000()) {
770 err = snd_ac97_pcm_assign(chip->ac97_bus,
771 ARRAY_SIZE(at91_ac97_pcm_defs),
772 at91_ac97_pcm_defs);
773 if (err)
774 return err;
775 }
620 retval = snd_pcm_new(chip->card, chip->card->shortname, 776 retval = snd_pcm_new(chip->card, chip->card->shortname,
621 chip->pdev->id, playback, capture, &pcm); 777 chip->pdev->id, playback, capture, &pcm);
622 if (retval) 778 if (retval)
@@ -775,7 +931,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
775 return -ENXIO; 931 return -ENXIO;
776 } 932 }
777 933
778 pclk = clk_get(&pdev->dev, "pclk"); 934 if (cpu_is_at32ap7000()) {
935 pclk = clk_get(&pdev->dev, "pclk");
936 } else {
937 pclk = clk_get(&pdev->dev, "ac97_clk");
938 }
939
779 if (IS_ERR(pclk)) { 940 if (IS_ERR(pclk)) {
780 dev_dbg(&pdev->dev, "no peripheral clock\n"); 941 dev_dbg(&pdev->dev, "no peripheral clock\n");
781 return PTR_ERR(pclk); 942 return PTR_ERR(pclk);
@@ -844,43 +1005,52 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
844 goto err_ac97_bus; 1005 goto err_ac97_bus;
845 } 1006 }
846 1007
847 if (pdata->rx_dws.dma_dev) { 1008 if (cpu_is_at32ap7000()) {
848 struct dw_dma_slave *dws = &pdata->rx_dws; 1009 if (pdata->rx_dws.dma_dev) {
849 dma_cap_mask_t mask; 1010 struct dw_dma_slave *dws = &pdata->rx_dws;
1011 dma_cap_mask_t mask;
850 1012
851 dws->rx_reg = regs->start + AC97C_CARHR + 2; 1013 dws->rx_reg = regs->start + AC97C_CARHR + 2;
852 1014
853 dma_cap_zero(mask); 1015 dma_cap_zero(mask);
854 dma_cap_set(DMA_SLAVE, mask); 1016 dma_cap_set(DMA_SLAVE, mask);
855 1017
856 chip->dma.rx_chan = dma_request_channel(mask, filter, dws); 1018 chip->dma.rx_chan = dma_request_channel(mask, filter,
1019 dws);
857 1020
858 dev_info(&chip->pdev->dev, "using %s for DMA RX\n", 1021 dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
859 dev_name(&chip->dma.rx_chan->dev->device)); 1022 dev_name(&chip->dma.rx_chan->dev->device));
860 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1023 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
861 } 1024 }
862 1025
863 if (pdata->tx_dws.dma_dev) { 1026 if (pdata->tx_dws.dma_dev) {
864 struct dw_dma_slave *dws = &pdata->tx_dws; 1027 struct dw_dma_slave *dws = &pdata->tx_dws;
865 dma_cap_mask_t mask; 1028 dma_cap_mask_t mask;
866 1029
867 dws->tx_reg = regs->start + AC97C_CATHR + 2; 1030 dws->tx_reg = regs->start + AC97C_CATHR + 2;
868 1031
869 dma_cap_zero(mask); 1032 dma_cap_zero(mask);
870 dma_cap_set(DMA_SLAVE, mask); 1033 dma_cap_set(DMA_SLAVE, mask);
871 1034
872 chip->dma.tx_chan = dma_request_channel(mask, filter, dws); 1035 chip->dma.tx_chan = dma_request_channel(mask, filter,
1036 dws);
873 1037
874 dev_info(&chip->pdev->dev, "using %s for DMA TX\n", 1038 dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
875 dev_name(&chip->dma.tx_chan->dev->device)); 1039 dev_name(&chip->dma.tx_chan->dev->device));
876 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1040 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
877 } 1041 }
878 1042
879 if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && 1043 if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) &&
880 !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { 1044 !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) {
881 dev_dbg(&pdev->dev, "DMA not available\n"); 1045 dev_dbg(&pdev->dev, "DMA not available\n");
882 retval = -ENODEV; 1046 retval = -ENODEV;
883 goto err_dma; 1047 goto err_dma;
1048 }
1049 } else {
1050 /* Just pretend that we have DMA channel(for at91 i is actually
1051 * the PDC) */
1052 set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
1053 set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
884 } 1054 }
885 1055
886 retval = atmel_ac97c_pcm_new(chip); 1056 retval = atmel_ac97c_pcm_new(chip);
@@ -897,20 +1067,22 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
897 1067
898 platform_set_drvdata(pdev, card); 1068 platform_set_drvdata(pdev, card);
899 1069
900 dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p\n", 1070 dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p, irq = %d\n",
901 chip->regs); 1071 chip->regs, irq);
902 1072
903 return 0; 1073 return 0;
904 1074
905err_dma: 1075err_dma:
906 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) 1076 if (cpu_is_at32ap7000()) {
907 dma_release_channel(chip->dma.rx_chan); 1077 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
908 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) 1078 dma_release_channel(chip->dma.rx_chan);
909 dma_release_channel(chip->dma.tx_chan); 1079 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
910 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1080 dma_release_channel(chip->dma.tx_chan);
911 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1081 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
912 chip->dma.rx_chan = NULL; 1082 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
913 chip->dma.tx_chan = NULL; 1083 chip->dma.rx_chan = NULL;
1084 chip->dma.tx_chan = NULL;
1085 }
914err_ac97_bus: 1086err_ac97_bus:
915 snd_card_set_dev(card, NULL); 1087 snd_card_set_dev(card, NULL);
916 1088
@@ -934,10 +1106,12 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
934 struct snd_card *card = platform_get_drvdata(pdev); 1106 struct snd_card *card = platform_get_drvdata(pdev);
935 struct atmel_ac97c *chip = card->private_data; 1107 struct atmel_ac97c *chip = card->private_data;
936 1108
937 if (test_bit(DMA_RX_READY, &chip->flags)) 1109 if (cpu_is_at32ap7000()) {
938 dw_dma_cyclic_stop(chip->dma.rx_chan); 1110 if (test_bit(DMA_RX_READY, &chip->flags))
939 if (test_bit(DMA_TX_READY, &chip->flags)) 1111 dw_dma_cyclic_stop(chip->dma.rx_chan);
940 dw_dma_cyclic_stop(chip->dma.tx_chan); 1112 if (test_bit(DMA_TX_READY, &chip->flags))
1113 dw_dma_cyclic_stop(chip->dma.tx_chan);
1114 }
941 clk_disable(chip->pclk); 1115 clk_disable(chip->pclk);
942 1116
943 return 0; 1117 return 0;
@@ -949,11 +1123,12 @@ static int atmel_ac97c_resume(struct platform_device *pdev)
949 struct atmel_ac97c *chip = card->private_data; 1123 struct atmel_ac97c *chip = card->private_data;
950 1124
951 clk_enable(chip->pclk); 1125 clk_enable(chip->pclk);
952 if (test_bit(DMA_RX_READY, &chip->flags)) 1126 if (cpu_is_at32ap7000()) {
953 dw_dma_cyclic_start(chip->dma.rx_chan); 1127 if (test_bit(DMA_RX_READY, &chip->flags))
954 if (test_bit(DMA_TX_READY, &chip->flags)) 1128 dw_dma_cyclic_start(chip->dma.rx_chan);
955 dw_dma_cyclic_start(chip->dma.tx_chan); 1129 if (test_bit(DMA_TX_READY, &chip->flags))
956 1130 dw_dma_cyclic_start(chip->dma.tx_chan);
1131 }
957 return 0; 1132 return 0;
958} 1133}
959#else 1134#else
@@ -978,14 +1153,16 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
978 iounmap(chip->regs); 1153 iounmap(chip->regs);
979 free_irq(chip->irq, chip); 1154 free_irq(chip->irq, chip);
980 1155
981 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) 1156 if (cpu_is_at32ap7000()) {
982 dma_release_channel(chip->dma.rx_chan); 1157 if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
983 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) 1158 dma_release_channel(chip->dma.rx_chan);
984 dma_release_channel(chip->dma.tx_chan); 1159 if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags))
985 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); 1160 dma_release_channel(chip->dma.tx_chan);
986 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); 1161 clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
987 chip->dma.rx_chan = NULL; 1162 clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
988 chip->dma.tx_chan = NULL; 1163 chip->dma.rx_chan = NULL;
1164 chip->dma.tx_chan = NULL;
1165 }
989 1166
990 snd_card_set_dev(card, NULL); 1167 snd_card_set_dev(card, NULL);
991 snd_card_free(card); 1168 snd_card_free(card);
diff --git a/sound/core/control.c b/sound/core/control.c
index 439ce64f9d82..070aab490191 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -50,6 +50,10 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
50 struct snd_ctl_file *ctl; 50 struct snd_ctl_file *ctl;
51 int err; 51 int err;
52 52
53 err = nonseekable_open(inode, file);
54 if (err < 0)
55 return err;
56
53 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); 57 card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
54 if (!card) { 58 if (!card) {
55 err = -ENODEV; 59 err = -ENODEV;
@@ -1388,6 +1392,7 @@ static const struct file_operations snd_ctl_f_ops =
1388 .read = snd_ctl_read, 1392 .read = snd_ctl_read,
1389 .open = snd_ctl_open, 1393 .open = snd_ctl_open,
1390 .release = snd_ctl_release, 1394 .release = snd_ctl_release,
1395 .llseek = no_llseek,
1391 .poll = snd_ctl_poll, 1396 .poll = snd_ctl_poll,
1392 .unlocked_ioctl = snd_ctl_ioctl, 1397 .unlocked_ioctl = snd_ctl_ioctl,
1393 .compat_ioctl = snd_ctl_ioctl_compat, 1398 .compat_ioctl = snd_ctl_ioctl_compat,
diff --git a/sound/core/info.c b/sound/core/info.c
index cc4a53d4b7f8..b70564ed8b37 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -164,40 +164,44 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
164{ 164{
165 struct snd_info_private_data *data; 165 struct snd_info_private_data *data;
166 struct snd_info_entry *entry; 166 struct snd_info_entry *entry;
167 loff_t ret; 167 loff_t ret = -EINVAL, size;
168 168
169 data = file->private_data; 169 data = file->private_data;
170 entry = data->entry; 170 entry = data->entry;
171 lock_kernel(); 171 mutex_lock(&entry->access);
172 switch (entry->content) { 172 if (entry->content == SNDRV_INFO_CONTENT_DATA &&
173 case SNDRV_INFO_CONTENT_TEXT: 173 entry->c.ops->llseek) {
174 switch (orig) { 174 offset = entry->c.ops->llseek(entry,
175 case SEEK_SET: 175 data->file_private_data,
176 file->f_pos = offset; 176 file, offset, orig);
177 ret = file->f_pos; 177 goto out;
178 goto out; 178 }
179 case SEEK_CUR: 179 if (entry->content == SNDRV_INFO_CONTENT_DATA)
180 file->f_pos += offset; 180 size = entry->size;
181 ret = file->f_pos; 181 else
182 goto out; 182 size = 0;
183 case SEEK_END: 183 switch (orig) {
184 default: 184 case SEEK_SET:
185 ret = -EINVAL;
186 goto out;
187 }
188 break; 185 break;
189 case SNDRV_INFO_CONTENT_DATA: 186 case SEEK_CUR:
190 if (entry->c.ops->llseek) { 187 offset += file->f_pos;
191 ret = entry->c.ops->llseek(entry, 188 break;
192 data->file_private_data, 189 case SEEK_END:
193 file, offset, orig); 190 if (!size)
194 goto out; 191 goto out;
195 } 192 offset += size;
196 break; 193 break;
197 } 194 default:
198 ret = -ENXIO; 195 goto out;
199out: 196 }
200 unlock_kernel(); 197 if (offset < 0)
198 goto out;
199 if (size && offset > size)
200 offset = size;
201 file->f_pos = offset;
202 ret = offset;
203 out:
204 mutex_unlock(&entry->access);
201 return ret; 205 return ret;
202} 206}
203 207
@@ -232,10 +236,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
232 return -EFAULT; 236 return -EFAULT;
233 break; 237 break;
234 case SNDRV_INFO_CONTENT_DATA: 238 case SNDRV_INFO_CONTENT_DATA:
235 if (entry->c.ops->read) 239 if (pos >= entry->size)
240 return 0;
241 if (entry->c.ops->read) {
242 size = entry->size - pos;
243 size = min(count, size);
236 size = entry->c.ops->read(entry, 244 size = entry->c.ops->read(entry,
237 data->file_private_data, 245 data->file_private_data,
238 file, buffer, count, pos); 246 file, buffer, size, pos);
247 }
239 break; 248 break;
240 } 249 }
241 if ((ssize_t) size > 0) 250 if ((ssize_t) size > 0)
@@ -282,10 +291,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer
282 size = count; 291 size = count;
283 break; 292 break;
284 case SNDRV_INFO_CONTENT_DATA: 293 case SNDRV_INFO_CONTENT_DATA:
285 if (entry->c.ops->write) 294 if (entry->c.ops->write && count > 0) {
295 size_t maxsize = entry->size - pos;
296 count = min(count, maxsize);
286 size = entry->c.ops->write(entry, 297 size = entry->c.ops->write(entry,
287 data->file_private_data, 298 data->file_private_data,
288 file, buffer, count, pos); 299 file, buffer, count, pos);
300 }
289 break; 301 break;
290 } 302 }
291 if ((ssize_t) size > 0) 303 if ((ssize_t) size > 0)
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 14b8a4ee690d..4902ae568730 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -24,7 +24,7 @@
24#include <sound/jack.h> 24#include <sound/jack.h>
25#include <sound/core.h> 25#include <sound/core.h>
26 26
27static int jack_types[] = { 27static int jack_switch_types[] = {
28 SW_HEADPHONE_INSERT, 28 SW_HEADPHONE_INSERT,
29 SW_MICROPHONE_INSERT, 29 SW_MICROPHONE_INSERT,
30 SW_LINEOUT_INSERT, 30 SW_LINEOUT_INSERT,
@@ -56,7 +56,7 @@ static int snd_jack_dev_register(struct snd_device *device)
56{ 56{
57 struct snd_jack *jack = device->device_data; 57 struct snd_jack *jack = device->device_data;
58 struct snd_card *card = device->card; 58 struct snd_card *card = device->card;
59 int err; 59 int err, i;
60 60
61 snprintf(jack->name, sizeof(jack->name), "%s %s", 61 snprintf(jack->name, sizeof(jack->name), "%s %s",
62 card->shortname, jack->id); 62 card->shortname, jack->id);
@@ -66,6 +66,19 @@ static int snd_jack_dev_register(struct snd_device *device)
66 if (!jack->input_dev->dev.parent) 66 if (!jack->input_dev->dev.parent)
67 jack->input_dev->dev.parent = snd_card_get_device_link(card); 67 jack->input_dev->dev.parent = snd_card_get_device_link(card);
68 68
69 /* Add capabilities for any keys that are enabled */
70 for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
71 int testbit = SND_JACK_BTN_0 >> i;
72
73 if (!(jack->type & testbit))
74 continue;
75
76 if (!jack->key[i])
77 jack->key[i] = BTN_0 + i;
78
79 input_set_capability(jack->input_dev, EV_KEY, jack->key[i]);
80 }
81
69 err = input_register_device(jack->input_dev); 82 err = input_register_device(jack->input_dev);
70 if (err == 0) 83 if (err == 0)
71 jack->registered = 1; 84 jack->registered = 1;
@@ -113,10 +126,10 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
113 126
114 jack->type = type; 127 jack->type = type;
115 128
116 for (i = 0; i < ARRAY_SIZE(jack_types); i++) 129 for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++)
117 if (type & (1 << i)) 130 if (type & (1 << i))
118 input_set_capability(jack->input_dev, EV_SW, 131 input_set_capability(jack->input_dev, EV_SW,
119 jack_types[i]); 132 jack_switch_types[i]);
120 133
121 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); 134 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
122 if (err < 0) 135 if (err < 0)
@@ -152,6 +165,43 @@ void snd_jack_set_parent(struct snd_jack *jack, struct device *parent)
152EXPORT_SYMBOL(snd_jack_set_parent); 165EXPORT_SYMBOL(snd_jack_set_parent);
153 166
154/** 167/**
168 * snd_jack_set_key - Set a key mapping on a jack
169 *
170 * @jack: The jack to configure
171 * @type: Jack report type for this key
172 * @keytype: Input layer key type to be reported
173 *
174 * Map a SND_JACK_BTN_ button type to an input layer key, allowing
175 * reporting of keys on accessories via the jack abstraction. If no
176 * mapping is provided but keys are enabled in the jack type then
177 * BTN_n numeric buttons will be reported.
178 *
179 * Note that this is intended to be use by simple devices with small
180 * numbers of keys that can be reported. It is also possible to
181 * access the input device directly - devices with complex input
182 * capabilities on accessories should consider doing this rather than
183 * using this abstraction.
184 *
185 * This function may only be called prior to registration of the jack.
186 */
187int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type,
188 int keytype)
189{
190 int key = fls(SND_JACK_BTN_0) - fls(type);
191
192 WARN_ON(jack->registered);
193
194 if (!keytype || key >= ARRAY_SIZE(jack->key))
195 return -EINVAL;
196
197 jack->type |= type;
198 jack->key[key] = keytype;
199
200 return 0;
201}
202EXPORT_SYMBOL(snd_jack_set_key);
203
204/**
155 * snd_jack_report - Report the current status of a jack 205 * snd_jack_report - Report the current status of a jack
156 * 206 *
157 * @jack: The jack to report status for 207 * @jack: The jack to report status for
@@ -164,10 +214,19 @@ void snd_jack_report(struct snd_jack *jack, int status)
164 if (!jack) 214 if (!jack)
165 return; 215 return;
166 216
167 for (i = 0; i < ARRAY_SIZE(jack_types); i++) { 217 for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
218 int testbit = SND_JACK_BTN_0 >> i;
219
220 if (jack->type & testbit)
221 input_report_key(jack->input_dev, jack->key[i],
222 status & testbit);
223 }
224
225 for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
168 int testbit = 1 << i; 226 int testbit = 1 << i;
169 if (jack->type & testbit) 227 if (jack->type & testbit)
170 input_report_switch(jack->input_dev, jack_types[i], 228 input_report_switch(jack->input_dev,
229 jack_switch_types[i],
171 status & testbit); 230 status & testbit);
172 } 231 }
173 232
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 54e2eb56e4c2..f50ebf20df96 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -43,6 +43,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
43 struct snd_mixer_oss_file *fmixer; 43 struct snd_mixer_oss_file *fmixer;
44 int err; 44 int err;
45 45
46 err = nonseekable_open(inode, file);
47 if (err < 0)
48 return err;
49
46 card = snd_lookup_oss_minor_data(iminor(inode), 50 card = snd_lookup_oss_minor_data(iminor(inode),
47 SNDRV_OSS_DEVICE_TYPE_MIXER); 51 SNDRV_OSS_DEVICE_TYPE_MIXER);
48 if (card == NULL) 52 if (card == NULL)
@@ -397,6 +401,7 @@ static const struct file_operations snd_mixer_oss_f_ops =
397 .owner = THIS_MODULE, 401 .owner = THIS_MODULE,
398 .open = snd_mixer_oss_open, 402 .open = snd_mixer_oss_open,
399 .release = snd_mixer_oss_release, 403 .release = snd_mixer_oss_release,
404 .llseek = no_llseek,
400 .unlocked_ioctl = snd_mixer_oss_ioctl, 405 .unlocked_ioctl = snd_mixer_oss_ioctl,
401 .compat_ioctl = snd_mixer_oss_ioctl_compat, 406 .compat_ioctl = snd_mixer_oss_ioctl_compat,
402}; 407};
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 82d4e3329b3d..5c8c7dff8ede 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2379,6 +2379,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
2379 int nonblock; 2379 int nonblock;
2380 wait_queue_t wait; 2380 wait_queue_t wait;
2381 2381
2382 err = nonseekable_open(inode, file);
2383 if (err < 0)
2384 return err;
2385
2382 pcm = snd_lookup_oss_minor_data(iminor(inode), 2386 pcm = snd_lookup_oss_minor_data(iminor(inode),
2383 SNDRV_OSS_DEVICE_TYPE_PCM); 2387 SNDRV_OSS_DEVICE_TYPE_PCM);
2384 if (pcm == NULL) { 2388 if (pcm == NULL) {
@@ -2977,6 +2981,7 @@ static const struct file_operations snd_pcm_oss_f_reg =
2977 .write = snd_pcm_oss_write, 2981 .write = snd_pcm_oss_write,
2978 .open = snd_pcm_oss_open, 2982 .open = snd_pcm_oss_open,
2979 .release = snd_pcm_oss_release, 2983 .release = snd_pcm_oss_release,
2984 .llseek = no_llseek,
2980 .poll = snd_pcm_oss_poll, 2985 .poll = snd_pcm_oss_poll,
2981 .unlocked_ioctl = snd_pcm_oss_ioctl, 2986 .unlocked_ioctl = snd_pcm_oss_ioctl,
2982 .compat_ioctl = snd_pcm_oss_ioctl_compat, 2987 .compat_ioctl = snd_pcm_oss_ioctl_compat,
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 0d428d0896db..cbe815dfbdc8 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -648,9 +648,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
648 substream->number = idx; 648 substream->number = idx;
649 substream->stream = stream; 649 substream->stream = stream;
650 sprintf(substream->name, "subdevice #%i", idx); 650 sprintf(substream->name, "subdevice #%i", idx);
651 snprintf(substream->latency_id, sizeof(substream->latency_id),
652 "ALSA-PCM%d-%d%c%d", pcm->card->number, pcm->device,
653 (stream ? 'c' : 'p'), idx);
654 substream->buffer_bytes_max = UINT_MAX; 651 substream->buffer_bytes_max = UINT_MAX;
655 if (prev == NULL) 652 if (prev == NULL)
656 pstr->substream = substream; 653 pstr->substream = substream;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 20b5982c996b..644c2bb17b86 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -484,11 +484,13 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
484 snd_pcm_timer_resolution_change(substream); 484 snd_pcm_timer_resolution_change(substream);
485 runtime->status->state = SNDRV_PCM_STATE_SETUP; 485 runtime->status->state = SNDRV_PCM_STATE_SETUP;
486 486
487 pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, 487 if (substream->latency_pm_qos_req) {
488 substream->latency_id); 488 pm_qos_remove_request(substream->latency_pm_qos_req);
489 substream->latency_pm_qos_req = NULL;
490 }
489 if ((usecs = period_to_usecs(runtime)) >= 0) 491 if ((usecs = period_to_usecs(runtime)) >= 0)
490 pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, 492 substream->latency_pm_qos_req = pm_qos_add_request(
491 substream->latency_id, usecs); 493 PM_QOS_CPU_DMA_LATENCY, usecs);
492 return 0; 494 return 0;
493 _error: 495 _error:
494 /* hardware might be unuseable from this time, 496 /* hardware might be unuseable from this time,
@@ -543,8 +545,8 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
543 if (substream->ops->hw_free) 545 if (substream->ops->hw_free)
544 result = substream->ops->hw_free(substream); 546 result = substream->ops->hw_free(substream);
545 runtime->status->state = SNDRV_PCM_STATE_OPEN; 547 runtime->status->state = SNDRV_PCM_STATE_OPEN;
546 pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, 548 pm_qos_remove_request(substream->latency_pm_qos_req);
547 substream->latency_id); 549 substream->latency_pm_qos_req = NULL;
548 return result; 550 return result;
549} 551}
550 552
@@ -2110,7 +2112,9 @@ static int snd_pcm_open_file(struct file *file,
2110static int snd_pcm_playback_open(struct inode *inode, struct file *file) 2112static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2111{ 2113{
2112 struct snd_pcm *pcm; 2114 struct snd_pcm *pcm;
2113 2115 int err = nonseekable_open(inode, file);
2116 if (err < 0)
2117 return err;
2114 pcm = snd_lookup_minor_data(iminor(inode), 2118 pcm = snd_lookup_minor_data(iminor(inode),
2115 SNDRV_DEVICE_TYPE_PCM_PLAYBACK); 2119 SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
2116 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); 2120 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
@@ -2119,7 +2123,9 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2119static int snd_pcm_capture_open(struct inode *inode, struct file *file) 2123static int snd_pcm_capture_open(struct inode *inode, struct file *file)
2120{ 2124{
2121 struct snd_pcm *pcm; 2125 struct snd_pcm *pcm;
2122 2126 int err = nonseekable_open(inode, file);
2127 if (err < 0)
2128 return err;
2123 pcm = snd_lookup_minor_data(iminor(inode), 2129 pcm = snd_lookup_minor_data(iminor(inode),
2124 SNDRV_DEVICE_TYPE_PCM_CAPTURE); 2130 SNDRV_DEVICE_TYPE_PCM_CAPTURE);
2125 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); 2131 return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
@@ -3310,18 +3316,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
3310 struct snd_pcm_file * pcm_file; 3316 struct snd_pcm_file * pcm_file;
3311 struct snd_pcm_substream *substream; 3317 struct snd_pcm_substream *substream;
3312 struct snd_pcm_runtime *runtime; 3318 struct snd_pcm_runtime *runtime;
3313 int err = -ENXIO;
3314 3319
3315 lock_kernel();
3316 pcm_file = file->private_data; 3320 pcm_file = file->private_data;
3317 substream = pcm_file->substream; 3321 substream = pcm_file->substream;
3318 if (PCM_RUNTIME_CHECK(substream)) 3322 if (PCM_RUNTIME_CHECK(substream))
3319 goto out; 3323 return -ENXIO;
3320 runtime = substream->runtime; 3324 runtime = substream->runtime;
3321 err = fasync_helper(fd, file, on, &runtime->fasync); 3325 return fasync_helper(fd, file, on, &runtime->fasync);
3322out:
3323 unlock_kernel();
3324 return err;
3325} 3326}
3326 3327
3327/* 3328/*
@@ -3441,14 +3442,28 @@ out:
3441#endif /* CONFIG_SND_SUPPORT_OLD_API */ 3442#endif /* CONFIG_SND_SUPPORT_OLD_API */
3442 3443
3443#ifndef CONFIG_MMU 3444#ifndef CONFIG_MMU
3444unsigned long dummy_get_unmapped_area(struct file *file, unsigned long addr, 3445static unsigned long snd_pcm_get_unmapped_area(struct file *file,
3445 unsigned long len, unsigned long pgoff, 3446 unsigned long addr,
3446 unsigned long flags) 3447 unsigned long len,
3447{ 3448 unsigned long pgoff,
3448 return 0; 3449 unsigned long flags)
3450{
3451 struct snd_pcm_file *pcm_file = file->private_data;
3452 struct snd_pcm_substream *substream = pcm_file->substream;
3453 struct snd_pcm_runtime *runtime = substream->runtime;
3454 unsigned long offset = pgoff << PAGE_SHIFT;
3455
3456 switch (offset) {
3457 case SNDRV_PCM_MMAP_OFFSET_STATUS:
3458 return (unsigned long)runtime->status;
3459 case SNDRV_PCM_MMAP_OFFSET_CONTROL:
3460 return (unsigned long)runtime->control;
3461 default:
3462 return (unsigned long)runtime->dma_area + offset;
3463 }
3449} 3464}
3450#else 3465#else
3451# define dummy_get_unmapped_area NULL 3466# define snd_pcm_get_unmapped_area NULL
3452#endif 3467#endif
3453 3468
3454/* 3469/*
@@ -3462,12 +3477,13 @@ const struct file_operations snd_pcm_f_ops[2] = {
3462 .aio_write = snd_pcm_aio_write, 3477 .aio_write = snd_pcm_aio_write,
3463 .open = snd_pcm_playback_open, 3478 .open = snd_pcm_playback_open,
3464 .release = snd_pcm_release, 3479 .release = snd_pcm_release,
3480 .llseek = no_llseek,
3465 .poll = snd_pcm_playback_poll, 3481 .poll = snd_pcm_playback_poll,
3466 .unlocked_ioctl = snd_pcm_playback_ioctl, 3482 .unlocked_ioctl = snd_pcm_playback_ioctl,
3467 .compat_ioctl = snd_pcm_ioctl_compat, 3483 .compat_ioctl = snd_pcm_ioctl_compat,
3468 .mmap = snd_pcm_mmap, 3484 .mmap = snd_pcm_mmap,
3469 .fasync = snd_pcm_fasync, 3485 .fasync = snd_pcm_fasync,
3470 .get_unmapped_area = dummy_get_unmapped_area, 3486 .get_unmapped_area = snd_pcm_get_unmapped_area,
3471 }, 3487 },
3472 { 3488 {
3473 .owner = THIS_MODULE, 3489 .owner = THIS_MODULE,
@@ -3475,11 +3491,12 @@ const struct file_operations snd_pcm_f_ops[2] = {
3475 .aio_read = snd_pcm_aio_read, 3491 .aio_read = snd_pcm_aio_read,
3476 .open = snd_pcm_capture_open, 3492 .open = snd_pcm_capture_open,
3477 .release = snd_pcm_release, 3493 .release = snd_pcm_release,
3494 .llseek = no_llseek,
3478 .poll = snd_pcm_capture_poll, 3495 .poll = snd_pcm_capture_poll,
3479 .unlocked_ioctl = snd_pcm_capture_ioctl, 3496 .unlocked_ioctl = snd_pcm_capture_ioctl,
3480 .compat_ioctl = snd_pcm_ioctl_compat, 3497 .compat_ioctl = snd_pcm_ioctl_compat,
3481 .mmap = snd_pcm_mmap, 3498 .mmap = snd_pcm_mmap,
3482 .fasync = snd_pcm_fasync, 3499 .fasync = snd_pcm_fasync,
3483 .get_unmapped_area = dummy_get_unmapped_area, 3500 .get_unmapped_area = snd_pcm_get_unmapped_area,
3484 } 3501 }
3485}; 3502};
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 0f5a194695d9..eb68326c37d4 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -376,6 +376,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
376 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 376 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
377 return -EINVAL; /* invalid combination */ 377 return -EINVAL; /* invalid combination */
378 378
379 err = nonseekable_open(inode, file);
380 if (err < 0)
381 return err;
382
379 if (maj == snd_major) { 383 if (maj == snd_major) {
380 rmidi = snd_lookup_minor_data(iminor(inode), 384 rmidi = snd_lookup_minor_data(iminor(inode),
381 SNDRV_DEVICE_TYPE_RAWMIDI); 385 SNDRV_DEVICE_TYPE_RAWMIDI);
@@ -1391,6 +1395,7 @@ static const struct file_operations snd_rawmidi_f_ops =
1391 .write = snd_rawmidi_write, 1395 .write = snd_rawmidi_write,
1392 .open = snd_rawmidi_open, 1396 .open = snd_rawmidi_open,
1393 .release = snd_rawmidi_release, 1397 .release = snd_rawmidi_release,
1398 .llseek = no_llseek,
1394 .poll = snd_rawmidi_poll, 1399 .poll = snd_rawmidi_poll,
1395 .unlocked_ioctl = snd_rawmidi_ioctl, 1400 .unlocked_ioctl = snd_rawmidi_ioctl,
1396 .compat_ioctl = snd_rawmidi_ioctl_compat, 1401 .compat_ioctl = snd_rawmidi_ioctl_compat,
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 48eca9ff9ee7..99a485f13648 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -318,6 +318,11 @@ static int snd_seq_open(struct inode *inode, struct file *file)
318 int c, mode; /* client id */ 318 int c, mode; /* client id */
319 struct snd_seq_client *client; 319 struct snd_seq_client *client;
320 struct snd_seq_user_client *user; 320 struct snd_seq_user_client *user;
321 int err;
322
323 err = nonseekable_open(inode, file);
324 if (err < 0)
325 return err;
321 326
322 if (mutex_lock_interruptible(&register_mutex)) 327 if (mutex_lock_interruptible(&register_mutex))
323 return -ERESTARTSYS; 328 return -ERESTARTSYS;
@@ -2550,6 +2555,7 @@ static const struct file_operations snd_seq_f_ops =
2550 .write = snd_seq_write, 2555 .write = snd_seq_write,
2551 .open = snd_seq_open, 2556 .open = snd_seq_open,
2552 .release = snd_seq_release, 2557 .release = snd_seq_release,
2558 .llseek = no_llseek,
2553 .poll = snd_seq_poll, 2559 .poll = snd_seq_poll,
2554 .unlocked_ioctl = snd_seq_ioctl, 2560 .unlocked_ioctl = snd_seq_ioctl,
2555 .compat_ioctl = snd_seq_ioctl_compat, 2561 .compat_ioctl = snd_seq_ioctl_compat,
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 563d1967a0ad..ac42af42b787 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
120 120
121EXPORT_SYMBOL(snd_lookup_minor_data); 121EXPORT_SYMBOL(snd_lookup_minor_data);
122 122
123static int __snd_open(struct inode *inode, struct file *file) 123#ifdef CONFIG_MODULES
124static struct snd_minor *autoload_device(unsigned int minor)
125{
126 int dev;
127 mutex_unlock(&sound_mutex); /* release lock temporarily */
128 dev = SNDRV_MINOR_DEVICE(minor);
129 if (dev == SNDRV_MINOR_CONTROL) {
130 /* /dev/aloadC? */
131 int card = SNDRV_MINOR_CARD(minor);
132 if (snd_cards[card] == NULL)
133 snd_request_card(card);
134 } else if (dev == SNDRV_MINOR_GLOBAL) {
135 /* /dev/aloadSEQ */
136 snd_request_other(minor);
137 }
138 mutex_lock(&sound_mutex); /* reacuire lock */
139 return snd_minors[minor];
140}
141#else /* !CONFIG_MODULES */
142#define autoload_device(minor) NULL
143#endif /* CONFIG_MODULES */
144
145static int snd_open(struct inode *inode, struct file *file)
124{ 146{
125 unsigned int minor = iminor(inode); 147 unsigned int minor = iminor(inode);
126 struct snd_minor *mptr = NULL; 148 struct snd_minor *mptr = NULL;
@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file)
129 151
130 if (minor >= ARRAY_SIZE(snd_minors)) 152 if (minor >= ARRAY_SIZE(snd_minors))
131 return -ENODEV; 153 return -ENODEV;
154 mutex_lock(&sound_mutex);
132 mptr = snd_minors[minor]; 155 mptr = snd_minors[minor];
133 if (mptr == NULL) { 156 if (mptr == NULL) {
134#ifdef CONFIG_MODULES 157 mptr = autoload_device(minor);
135 int dev = SNDRV_MINOR_DEVICE(minor); 158 if (!mptr) {
136 if (dev == SNDRV_MINOR_CONTROL) { 159 mutex_unlock(&sound_mutex);
137 /* /dev/aloadC? */
138 int card = SNDRV_MINOR_CARD(minor);
139 if (snd_cards[card] == NULL)
140 snd_request_card(card);
141 } else if (dev == SNDRV_MINOR_GLOBAL) {
142 /* /dev/aloadSEQ */
143 snd_request_other(minor);
144 }
145#ifndef CONFIG_SND_DYNAMIC_MINORS
146 /* /dev/snd/{controlC?,seq} */
147 mptr = snd_minors[minor];
148 if (mptr == NULL)
149#endif
150#endif
151 return -ENODEV; 160 return -ENODEV;
161 }
152 } 162 }
153 old_fops = file->f_op; 163 old_fops = file->f_op;
154 file->f_op = fops_get(mptr->f_ops); 164 file->f_op = fops_get(mptr->f_ops);
155 if (file->f_op == NULL) { 165 if (file->f_op == NULL) {
156 file->f_op = old_fops; 166 file->f_op = old_fops;
157 return -ENODEV; 167 err = -ENODEV;
158 } 168 }
159 if (file->f_op->open) 169 mutex_unlock(&sound_mutex);
170 if (err < 0)
171 return err;
172
173 if (file->f_op->open) {
160 err = file->f_op->open(inode, file); 174 err = file->f_op->open(inode, file);
161 if (err) { 175 if (err) {
162 fops_put(file->f_op); 176 fops_put(file->f_op);
163 file->f_op = fops_get(old_fops); 177 file->f_op = fops_get(old_fops);
178 }
164 } 179 }
165 fops_put(old_fops); 180 fops_put(old_fops);
166 return err; 181 return err;
167} 182}
168 183
169
170/* BKL pushdown: nasty #ifdef avoidance wrapper */
171static int snd_open(struct inode *inode, struct file *file)
172{
173 int ret;
174
175 lock_kernel();
176 ret = __snd_open(inode, file);
177 unlock_kernel();
178 return ret;
179}
180
181static const struct file_operations snd_fops = 184static const struct file_operations snd_fops =
182{ 185{
183 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 5040c7b862fe..13afb60999b9 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1238,6 +1238,11 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1238static int snd_timer_user_open(struct inode *inode, struct file *file) 1238static int snd_timer_user_open(struct inode *inode, struct file *file)
1239{ 1239{
1240 struct snd_timer_user *tu; 1240 struct snd_timer_user *tu;
1241 int err;
1242
1243 err = nonseekable_open(inode, file);
1244 if (err < 0)
1245 return err;
1241 1246
1242 tu = kzalloc(sizeof(*tu), GFP_KERNEL); 1247 tu = kzalloc(sizeof(*tu), GFP_KERNEL);
1243 if (tu == NULL) 1248 if (tu == NULL)
@@ -1922,6 +1927,7 @@ static const struct file_operations snd_timer_f_ops =
1922 .read = snd_timer_user_read, 1927 .read = snd_timer_user_read,
1923 .open = snd_timer_user_open, 1928 .open = snd_timer_user_open,
1924 .release = snd_timer_user_release, 1929 .release = snd_timer_user_release,
1930 .llseek = no_llseek,
1925 .poll = snd_timer_user_poll, 1931 .poll = snd_timer_user_poll,
1926 .unlocked_ioctl = snd_timer_user_ioctl, 1932 .unlocked_ioctl = snd_timer_user_ioctl,
1927 .compat_ioctl = snd_timer_user_ioctl_compat, 1933 .compat_ioctl = snd_timer_user_ioctl_compat,
diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c
index 1679300b7583..df850b8830a5 100644
--- a/sound/drivers/opl4/opl4_proc.c
+++ b/sound/drivers/opl4/opl4_proc.c
@@ -49,77 +49,45 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
49 return 0; 49 return 0;
50} 50}
51 51
52static long snd_opl4_mem_proc_read(struct snd_info_entry *entry, void *file_private_data, 52static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry,
53 struct file *file, char __user *_buf, 53 void *file_private_data,
54 unsigned long count, unsigned long pos) 54 struct file *file, char __user *_buf,
55 size_t count, loff_t pos)
55{ 56{
56 struct snd_opl4 *opl4 = entry->private_data; 57 struct snd_opl4 *opl4 = entry->private_data;
57 long size;
58 char* buf; 58 char* buf;
59 59
60 size = count; 60 buf = vmalloc(count);
61 if (pos + size > entry->size) 61 if (!buf)
62 size = entry->size - pos; 62 return -ENOMEM;
63 if (size > 0) { 63 snd_opl4_read_memory(opl4, buf, pos, count);
64 buf = vmalloc(size); 64 if (copy_to_user(_buf, buf, count)) {
65 if (!buf)
66 return -ENOMEM;
67 snd_opl4_read_memory(opl4, buf, pos, size);
68 if (copy_to_user(_buf, buf, size)) {
69 vfree(buf);
70 return -EFAULT;
71 }
72 vfree(buf); 65 vfree(buf);
73 return size; 66 return -EFAULT;
74 } 67 }
75 return 0; 68 vfree(buf);
69 return count;
76} 70}
77 71
78static long snd_opl4_mem_proc_write(struct snd_info_entry *entry, void *file_private_data, 72static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry,
79 struct file *file, const char __user *_buf, 73 void *file_private_data,
80 unsigned long count, unsigned long pos) 74 struct file *file,
75 const char __user *_buf,
76 size_t count, loff_t pos)
81{ 77{
82 struct snd_opl4 *opl4 = entry->private_data; 78 struct snd_opl4 *opl4 = entry->private_data;
83 long size;
84 char *buf; 79 char *buf;
85 80
86 size = count; 81 buf = vmalloc(count);
87 if (pos + size > entry->size) 82 if (!buf)
88 size = entry->size - pos; 83 return -ENOMEM;
89 if (size > 0) { 84 if (copy_from_user(buf, _buf, count)) {
90 buf = vmalloc(size);
91 if (!buf)
92 return -ENOMEM;
93 if (copy_from_user(buf, _buf, size)) {
94 vfree(buf);
95 return -EFAULT;
96 }
97 snd_opl4_write_memory(opl4, buf, pos, size);
98 vfree(buf); 85 vfree(buf);
99 return size; 86 return -EFAULT;
100 }
101 return 0;
102}
103
104static long long snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, void *file_private_data,
105 struct file *file, long long offset, int orig)
106{
107 switch (orig) {
108 case SEEK_SET:
109 file->f_pos = offset;
110 break;
111 case SEEK_CUR:
112 file->f_pos += offset;
113 break;
114 case SEEK_END: /* offset is negative */
115 file->f_pos = entry->size + offset;
116 break;
117 default:
118 return -EINVAL;
119 } 87 }
120 if (file->f_pos > entry->size) 88 snd_opl4_write_memory(opl4, buf, pos, count);
121 file->f_pos = entry->size; 89 vfree(buf);
122 return file->f_pos; 90 return count;
123} 91}
124 92
125static struct snd_info_entry_ops snd_opl4_mem_proc_ops = { 93static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
@@ -127,7 +95,6 @@ static struct snd_info_entry_ops snd_opl4_mem_proc_ops = {
127 .release = snd_opl4_mem_proc_release, 95 .release = snd_opl4_mem_proc_release,
128 .read = snd_opl4_mem_proc_read, 96 .read = snd_opl4_mem_proc_read,
129 .write = snd_opl4_mem_proc_write, 97 .write = snd_opl4_mem_proc_write,
130 .llseek = snd_opl4_mem_proc_llseek,
131}; 98};
132 99
133int snd_opl4_create_proc(struct snd_opl4 *opl4) 100int snd_opl4_create_proc(struct snd_opl4 *opl4)
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 1e123077923d..4ff6c8cc5077 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -16,7 +16,7 @@
16#include <asm/i8253.h> 16#include <asm/i8253.h>
17#else 17#else
18#include <asm/8253pit.h> 18#include <asm/8253pit.h>
19static DEFINE_SPINLOCK(i8253_lock); 19static DEFINE_RAW_SPINLOCK(i8253_lock);
20#endif 20#endif
21 21
22#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */ 22#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */
diff --git a/sound/drivers/pcsp/pcsp_input.c b/sound/drivers/pcsp/pcsp_input.c
index 0444cdeb4bec..b5e2b54c2604 100644
--- a/sound/drivers/pcsp/pcsp_input.c
+++ b/sound/drivers/pcsp/pcsp_input.c
@@ -21,7 +21,7 @@ static void pcspkr_do_sound(unsigned int count)
21{ 21{
22 unsigned long flags; 22 unsigned long flags;
23 23
24 spin_lock_irqsave(&i8253_lock, flags); 24 raw_spin_lock_irqsave(&i8253_lock, flags);
25 25
26 if (count) { 26 if (count) {
27 /* set command for counter 2, 2 byte write */ 27 /* set command for counter 2, 2 byte write */
@@ -36,7 +36,7 @@ static void pcspkr_do_sound(unsigned int count)
36 outb(inb_p(0x61) & 0xFC, 0x61); 36 outb(inb_p(0x61) & 0xFC, 0x61);
37 } 37 }
38 38
39 spin_unlock_irqrestore(&i8253_lock, flags); 39 raw_spin_unlock_irqrestore(&i8253_lock, flags);
40} 40}
41 41
42void pcspkr_stop_sound(void) 42void pcspkr_stop_sound(void)
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index d77ffa9a9387..ce9e7d170c0d 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -66,7 +66,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip)
66 timer_cnt = val * CUR_DIV() / 256; 66 timer_cnt = val * CUR_DIV() / 256;
67 67
68 if (timer_cnt && chip->enable) { 68 if (timer_cnt && chip->enable) {
69 spin_lock_irqsave(&i8253_lock, flags); 69 raw_spin_lock_irqsave(&i8253_lock, flags);
70 if (!nforce_wa) { 70 if (!nforce_wa) {
71 outb_p(chip->val61, 0x61); 71 outb_p(chip->val61, 0x61);
72 outb_p(timer_cnt, 0x42); 72 outb_p(timer_cnt, 0x42);
@@ -75,7 +75,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip)
75 outb(chip->val61 ^ 2, 0x61); 75 outb(chip->val61 ^ 2, 0x61);
76 chip->thalf = 1; 76 chip->thalf = 1;
77 } 77 }
78 spin_unlock_irqrestore(&i8253_lock, flags); 78 raw_spin_unlock_irqrestore(&i8253_lock, flags);
79 } 79 }
80 80
81 chip->ns_rem = PCSP_PERIOD_NS(); 81 chip->ns_rem = PCSP_PERIOD_NS();
@@ -159,10 +159,10 @@ static int pcsp_start_playing(struct snd_pcsp *chip)
159 return -EIO; 159 return -EIO;
160 } 160 }
161 161
162 spin_lock(&i8253_lock); 162 raw_spin_lock(&i8253_lock);
163 chip->val61 = inb(0x61) | 0x03; 163 chip->val61 = inb(0x61) | 0x03;
164 outb_p(0x92, 0x43); /* binary, mode 1, LSB only, ch 2 */ 164 outb_p(0x92, 0x43); /* binary, mode 1, LSB only, ch 2 */
165 spin_unlock(&i8253_lock); 165 raw_spin_unlock(&i8253_lock);
166 atomic_set(&chip->timer_active, 1); 166 atomic_set(&chip->timer_active, 1);
167 chip->thalf = 0; 167 chip->thalf = 0;
168 168
@@ -179,11 +179,11 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
179 return; 179 return;
180 180
181 atomic_set(&chip->timer_active, 0); 181 atomic_set(&chip->timer_active, 0);
182 spin_lock(&i8253_lock); 182 raw_spin_lock(&i8253_lock);
183 /* restore the timer */ 183 /* restore the timer */
184 outb_p(0xb6, 0x43); /* binary, mode 3, LSB/MSB, ch 2 */ 184 outb_p(0xb6, 0x43); /* binary, mode 3, LSB/MSB, ch 2 */
185 outb(chip->val61 & 0xFC, 0x61); 185 outb(chip->val61 & 0xFC, 0x61);
186 spin_unlock(&i8253_lock); 186 raw_spin_unlock(&i8253_lock);
187} 187}
188 188
189/* 189/*
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index 5c0c77dd01c3..eb7c7d05a7c1 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -98,7 +98,8 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name,
98 bus->master = master; 98 bus->master = master;
99 } 99 }
100 strlcpy(bus->name, name, sizeof(bus->name)); 100 strlcpy(bus->name, name, sizeof(bus->name));
101 if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops)) < 0) { 101 err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops);
102 if (err < 0) {
102 snd_i2c_bus_free(bus); 103 snd_i2c_bus_free(bus);
103 return err; 104 return err;
104 } 105 }
@@ -246,7 +247,8 @@ static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data)
246 247
247 for (i = 7; i >= 0; i--) 248 for (i = 7; i >= 0; i--)
248 snd_i2c_bit_send(bus, !!(data & (1 << i))); 249 snd_i2c_bit_send(bus, !!(data & (1 << i)));
249 if ((err = snd_i2c_bit_ack(bus)) < 0) 250 err = snd_i2c_bit_ack(bus);
251 if (err < 0)
250 return err; 252 return err;
251 return 0; 253 return 0;
252} 254}
@@ -278,12 +280,14 @@ static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
278 if (device->flags & SND_I2C_DEVICE_ADDRTEN) 280 if (device->flags & SND_I2C_DEVICE_ADDRTEN)
279 return -EIO; /* not yet implemented */ 281 return -EIO; /* not yet implemented */
280 snd_i2c_bit_start(bus); 282 snd_i2c_bit_start(bus);
281 if ((err = snd_i2c_bit_sendbyte(bus, device->addr << 1)) < 0) { 283 err = snd_i2c_bit_sendbyte(bus, device->addr << 1);
284 if (err < 0) {
282 snd_i2c_bit_hw_stop(bus); 285 snd_i2c_bit_hw_stop(bus);
283 return err; 286 return err;
284 } 287 }
285 while (count-- > 0) { 288 while (count-- > 0) {
286 if ((err = snd_i2c_bit_sendbyte(bus, *bytes++)) < 0) { 289 err = snd_i2c_bit_sendbyte(bus, *bytes++);
290 if (err < 0) {
287 snd_i2c_bit_hw_stop(bus); 291 snd_i2c_bit_hw_stop(bus);
288 return err; 292 return err;
289 } 293 }
@@ -302,12 +306,14 @@ static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
302 if (device->flags & SND_I2C_DEVICE_ADDRTEN) 306 if (device->flags & SND_I2C_DEVICE_ADDRTEN)
303 return -EIO; /* not yet implemented */ 307 return -EIO; /* not yet implemented */
304 snd_i2c_bit_start(bus); 308 snd_i2c_bit_start(bus);
305 if ((err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1)) < 0) { 309 err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1);
310 if (err < 0) {
306 snd_i2c_bit_hw_stop(bus); 311 snd_i2c_bit_hw_stop(bus);
307 return err; 312 return err;
308 } 313 }
309 while (count-- > 0) { 314 while (count-- > 0) {
310 if ((err = snd_i2c_bit_readbyte(bus, count == 0)) < 0) { 315 err = snd_i2c_bit_readbyte(bus, count == 0);
316 if (err < 0) {
311 snd_i2c_bit_hw_stop(bus); 317 snd_i2c_bit_hw_stop(bus);
312 return err; 318 return err;
313 } 319 }
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 755a0a5f0e3f..c6990c680796 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -128,26 +128,14 @@ config SND_CS4236
128 To compile this driver as a module, choose M here: the module 128 To compile this driver as a module, choose M here: the module
129 will be called snd-cs4236. 129 will be called snd-cs4236.
130 130
131config SND_ES968
132 tristate "Generic ESS ES968 driver"
133 depends on PNP
134 select ISAPNP
135 select SND_MPU401_UART
136 select SND_SB8_DSP
137 help
138 Say Y here to include support for ESS AudioDrive ES968 chips.
139
140 To compile this driver as a module, choose M here: the module
141 will be called snd-es968.
142
143config SND_ES1688 131config SND_ES1688
144 tristate "Generic ESS ES688/ES1688 driver" 132 tristate "Generic ESS ES688/ES1688 and ES968 PnP driver"
145 select SND_OPL3_LIB 133 select SND_OPL3_LIB
146 select SND_MPU401_UART 134 select SND_MPU401_UART
147 select SND_PCM 135 select SND_PCM
148 help 136 help
149 Say Y here to include support for ESS AudioDrive ES688 or 137 Say Y here to include support for ESS AudioDrive ES688 or
150 ES1688 chips. 138 ES1688 chips. Also, this module support cards with ES968 PnP chip.
151 139
152 To compile this driver as a module, choose M here: the module 140 To compile this driver as a module, choose M here: the module
153 will be called snd-es1688. 141 will be called snd-es1688.
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 07df201ed8fa..0cde8131a575 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/isa.h> 24#include <linux/isa.h>
25#include <linux/isapnp.h>
25#include <linux/time.h> 26#include <linux/time.h>
26#include <linux/wait.h> 27#include <linux/wait.h>
27#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
@@ -45,8 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
45 "{ESS,ES688 AudioDrive,pnp:ESS6881}," 46 "{ESS,ES688 AudioDrive,pnp:ESS6881},"
46 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}"); 47 "{ESS,ES1688 AudioDrive,pnp:ESS1681}}");
47 48
49MODULE_ALIAS("snd_es968");
50
48static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
49static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
53#ifdef CONFIG_PNP
54static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
55#endif
50static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ 56static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
51static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ 57static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
52static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ 58static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */
@@ -60,6 +66,10 @@ MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
60module_param_array(id, charp, NULL, 0444); 66module_param_array(id, charp, NULL, 0444);
61MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); 67MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
62module_param_array(enable, bool, NULL, 0444); 68module_param_array(enable, bool, NULL, 0444);
69#ifdef CONFIG_PNP
70module_param_array(isapnp, bool, NULL, 0444);
71MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
72#endif
63MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); 73MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
64module_param_array(port, long, NULL, 0444); 74module_param_array(port, long, NULL, 0444);
65MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); 75MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
@@ -74,14 +84,21 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
74module_param_array(dma8, int, NULL, 0444); 84module_param_array(dma8, int, NULL, 0444);
75MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); 85MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
76 86
87#ifdef CONFIG_PNP
88#define is_isapnp_selected(dev) isapnp[dev]
89#else
90#define is_isapnp_selected(dev) 0
91#endif
92
77static int __devinit snd_es1688_match(struct device *dev, unsigned int n) 93static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
78{ 94{
79 return enable[n]; 95 return enable[n] && !is_isapnp_selected(n);
80} 96}
81 97
82static int __devinit snd_es1688_legacy_create(struct snd_card *card, 98static int __devinit snd_es1688_legacy_create(struct snd_card *card,
83 struct device *dev, unsigned int n, struct snd_es1688 **rchip) 99 struct device *dev, unsigned int n)
84{ 100{
101 struct snd_es1688 *chip = card->private_data;
85 static long possible_ports[] = {0x220, 0x240, 0x260}; 102 static long possible_ports[] = {0x220, 0x240, 0x260};
86 static int possible_irqs[] = {5, 9, 10, 7, -1}; 103 static int possible_irqs[] = {5, 9, 10, 7, -1};
87 static int possible_dmas[] = {1, 3, 0, -1}; 104 static int possible_dmas[] = {1, 3, 0, -1};
@@ -104,47 +121,39 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card,
104 } 121 }
105 122
106 if (port[n] != SNDRV_AUTO_PORT) 123 if (port[n] != SNDRV_AUTO_PORT)
107 return snd_es1688_create(card, port[n], mpu_port[n], irq[n], 124 return snd_es1688_create(card, chip, port[n], mpu_port[n],
108 mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); 125 irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
109 126
110 i = 0; 127 i = 0;
111 do { 128 do {
112 port[n] = possible_ports[i]; 129 port[n] = possible_ports[i];
113 error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], 130 error = snd_es1688_create(card, chip, port[n], mpu_port[n],
114 mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); 131 irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
115 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); 132 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
116 133
117 return error; 134 return error;
118} 135}
119 136
120static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) 137static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
121{ 138{
122 struct snd_card *card; 139 struct snd_es1688 *chip = card->private_data;
123 struct snd_es1688 *chip;
124 struct snd_opl3 *opl3; 140 struct snd_opl3 *opl3;
125 struct snd_pcm *pcm; 141 struct snd_pcm *pcm;
126 int error; 142 int error;
127 143
128 error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); 144 error = snd_es1688_pcm(card, chip, 0, &pcm);
129 if (error < 0) 145 if (error < 0)
130 return error; 146 return error;
131 147
132 error = snd_es1688_legacy_create(card, dev, n, &chip); 148 error = snd_es1688_mixer(card, chip);
133 if (error < 0)
134 goto out;
135
136 error = snd_es1688_pcm(chip, 0, &pcm);
137 if (error < 0) 149 if (error < 0)
138 goto out; 150 return error;
139
140 error = snd_es1688_mixer(chip);
141 if (error < 0)
142 goto out;
143 151
144 strcpy(card->driver, "ES1688"); 152 strlcpy(card->driver, "ES1688", sizeof(card->driver));
145 strcpy(card->shortname, pcm->name); 153 strlcpy(card->shortname, pcm->name, sizeof(card->shortname));
146 sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, 154 snprintf(card->longname, sizeof(card->longname),
147 chip->port, chip->irq, chip->dma8); 155 "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port,
156 chip->irq, chip->dma8);
148 157
149 if (fm_port[n] == SNDRV_AUTO_PORT) 158 if (fm_port[n] == SNDRV_AUTO_PORT)
150 fm_port[n] = port[n]; /* share the same port */ 159 fm_port[n] = port[n]; /* share the same port */
@@ -152,12 +161,12 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
152 if (fm_port[n] > 0) { 161 if (fm_port[n] > 0) {
153 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, 162 if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
154 OPL3_HW_OPL3, 0, &opl3) < 0) 163 OPL3_HW_OPL3, 0, &opl3) < 0)
155 dev_warn(dev, 164 dev_warn(card->dev,
156 "opl3 not detected at 0x%lx\n", fm_port[n]); 165 "opl3 not detected at 0x%lx\n", fm_port[n]);
157 else { 166 else {
158 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 167 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
159 if (error < 0) 168 if (error < 0)
160 goto out; 169 return error;
161 } 170 }
162 } 171 }
163 172
@@ -167,23 +176,41 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
167 chip->mpu_port, 0, 176 chip->mpu_port, 0,
168 mpu_irq[n], IRQF_DISABLED, NULL); 177 mpu_irq[n], IRQF_DISABLED, NULL);
169 if (error < 0) 178 if (error < 0)
170 goto out; 179 return error;
171 } 180 }
172 181
182 return snd_card_register(card);
183}
184
185static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n)
186{
187 struct snd_card *card;
188 int error;
189
190 error = snd_card_create(index[n], id[n], THIS_MODULE,
191 sizeof(struct snd_es1688), &card);
192 if (error < 0)
193 return error;
194
195 error = snd_es1688_legacy_create(card, dev, n);
196 if (error < 0)
197 goto out;
198
173 snd_card_set_dev(card, dev); 199 snd_card_set_dev(card, dev);
174 200
175 error = snd_card_register(card); 201 error = snd_es1688_probe(card, n);
176 if (error < 0) 202 if (error < 0)
177 goto out; 203 goto out;
178 204
179 dev_set_drvdata(dev, card); 205 dev_set_drvdata(dev, card);
180 return 0;
181 206
182out: snd_card_free(card); 207 return 0;
208out:
209 snd_card_free(card);
183 return error; 210 return error;
184} 211}
185 212
186static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) 213static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n)
187{ 214{
188 snd_card_free(dev_get_drvdata(dev)); 215 snd_card_free(dev_get_drvdata(dev));
189 dev_set_drvdata(dev, NULL); 216 dev_set_drvdata(dev, NULL);
@@ -192,8 +219,8 @@ static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
192 219
193static struct isa_driver snd_es1688_driver = { 220static struct isa_driver snd_es1688_driver = {
194 .match = snd_es1688_match, 221 .match = snd_es1688_match,
195 .probe = snd_es1688_probe, 222 .probe = snd_es1688_isa_probe,
196 .remove = __devexit_p(snd_es1688_remove), 223 .remove = __devexit_p(snd_es1688_isa_remove),
197#if 0 /* FIXME */ 224#if 0 /* FIXME */
198 .suspend = snd_es1688_suspend, 225 .suspend = snd_es1688_suspend,
199 .resume = snd_es1688_resume, 226 .resume = snd_es1688_resume,
@@ -203,14 +230,142 @@ static struct isa_driver snd_es1688_driver = {
203 } 230 }
204}; 231};
205 232
233static int snd_es968_pnp_is_probed;
234
235#ifdef CONFIG_PNP
236static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n,
237 struct pnp_card_link *pcard,
238 const struct pnp_card_device_id *pid)
239{
240 struct snd_es1688 *chip = card->private_data;
241 struct pnp_dev *pdev;
242 int error;
243
244 pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
245 if (pdev == NULL)
246 return -ENODEV;
247
248 error = pnp_activate_dev(pdev);
249 if (error < 0) {
250 snd_printk(KERN_ERR "ES968 pnp configure failure\n");
251 return error;
252 }
253 port[n] = pnp_port_start(pdev, 0);
254 dma8[n] = pnp_dma(pdev, 0);
255 irq[n] = pnp_irq(pdev, 0);
256
257 return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n],
258 mpu_irq[n], dma8[n], ES1688_HW_AUTO);
259}
260
261static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard,
262 const struct pnp_card_device_id *pid)
263{
264 struct snd_card *card;
265 static unsigned int dev;
266 int error;
267 struct snd_es1688 *chip;
268
269 if (snd_es968_pnp_is_probed)
270 return -EBUSY;
271 for ( ; dev < SNDRV_CARDS; dev++) {
272 if (enable[dev] && isapnp[dev])
273 break;
274 }
275 if (dev == SNDRV_CARDS)
276 return -ENODEV;
277
278 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
279 sizeof(struct snd_es1688), &card);
280 if (error < 0)
281 return error;
282 chip = card->private_data;
283
284 error = snd_card_es968_pnp(card, dev, pcard, pid);
285 if (error < 0) {
286 snd_card_free(card);
287 return error;
288 }
289 snd_card_set_dev(card, &pcard->card->dev);
290 error = snd_es1688_probe(card, dev);
291 if (error < 0)
292 return error;
293 pnp_set_card_drvdata(pcard, card);
294 snd_es968_pnp_is_probed = 1;
295 return 0;
296}
297
298static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
299{
300 snd_card_free(pnp_get_card_drvdata(pcard));
301 pnp_set_card_drvdata(pcard, NULL);
302 snd_es968_pnp_is_probed = 0;
303}
304
305#ifdef CONFIG_PM
306static int snd_es968_pnp_suspend(struct pnp_card_link *pcard,
307 pm_message_t state)
308{
309 struct snd_card *card = pnp_get_card_drvdata(pcard);
310 struct snd_es1688 *chip = card->private_data;
311
312 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
313 snd_pcm_suspend_all(chip->pcm);
314 return 0;
315}
316
317static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
318{
319 struct snd_card *card = pnp_get_card_drvdata(pcard);
320 struct snd_es1688 *chip = card->private_data;
321
322 snd_es1688_reset(chip);
323 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
324 return 0;
325}
326#endif
327
328static struct pnp_card_device_id snd_es968_pnpids[] = {
329 { .id = "ESS0968", .devs = { { "@@@0968" }, } },
330 { .id = "ESS0968", .devs = { { "ESS0968" }, } },
331 { .id = "", } /* end */
332};
333
334MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
335
336static struct pnp_card_driver es968_pnpc_driver = {
337 .flags = PNP_DRIVER_RES_DISABLE,
338 .name = DEV_NAME " PnP",
339 .id_table = snd_es968_pnpids,
340 .probe = snd_es968_pnp_detect,
341 .remove = __devexit_p(snd_es968_pnp_remove),
342#ifdef CONFIG_PM
343 .suspend = snd_es968_pnp_suspend,
344 .resume = snd_es968_pnp_resume,
345#endif
346};
347#endif
348
206static int __init alsa_card_es1688_init(void) 349static int __init alsa_card_es1688_init(void)
207{ 350{
351#ifdef CONFIG_PNP
352 pnp_register_card_driver(&es968_pnpc_driver);
353 if (snd_es968_pnp_is_probed)
354 return 0;
355 pnp_unregister_card_driver(&es968_pnpc_driver);
356#endif
208 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); 357 return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
209} 358}
210 359
211static void __exit alsa_card_es1688_exit(void) 360static void __exit alsa_card_es1688_exit(void)
212{ 361{
213 isa_unregister_driver(&snd_es1688_driver); 362 if (!snd_es968_pnp_is_probed) {
363 isa_unregister_driver(&snd_es1688_driver);
364 return;
365 }
366#ifdef CONFIG_PNP
367 pnp_unregister_card_driver(&es968_pnpc_driver);
368#endif
214} 369}
215 370
216module_init(alsa_card_es1688_init); 371module_init(alsa_card_es1688_init);
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index c76bb00c9d15..07676200496a 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -99,7 +99,7 @@ static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned cha
99 return result; 99 return result;
100} 100}
101 101
102static int snd_es1688_reset(struct snd_es1688 *chip) 102int snd_es1688_reset(struct snd_es1688 *chip)
103{ 103{
104 int i; 104 int i;
105 105
@@ -115,6 +115,7 @@ static int snd_es1688_reset(struct snd_es1688 *chip)
115 snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */ 115 snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */
116 return 0; 116 return 0;
117} 117}
118EXPORT_SYMBOL(snd_es1688_reset);
118 119
119static int snd_es1688_probe(struct snd_es1688 *chip) 120static int snd_es1688_probe(struct snd_es1688 *chip)
120{ 121{
@@ -620,7 +621,6 @@ static int snd_es1688_free(struct snd_es1688 *chip)
620 disable_dma(chip->dma8); 621 disable_dma(chip->dma8);
621 free_dma(chip->dma8); 622 free_dma(chip->dma8);
622 } 623 }
623 kfree(chip);
624 return 0; 624 return 0;
625} 625}
626 626
@@ -638,23 +638,20 @@ static const char *snd_es1688_chip_id(struct snd_es1688 *chip)
638} 638}
639 639
640int snd_es1688_create(struct snd_card *card, 640int snd_es1688_create(struct snd_card *card,
641 struct snd_es1688 *chip,
641 unsigned long port, 642 unsigned long port,
642 unsigned long mpu_port, 643 unsigned long mpu_port,
643 int irq, 644 int irq,
644 int mpu_irq, 645 int mpu_irq,
645 int dma8, 646 int dma8,
646 unsigned short hardware, 647 unsigned short hardware)
647 struct snd_es1688 **rchip)
648{ 648{
649 static struct snd_device_ops ops = { 649 static struct snd_device_ops ops = {
650 .dev_free = snd_es1688_dev_free, 650 .dev_free = snd_es1688_dev_free,
651 }; 651 };
652 652
653 struct snd_es1688 *chip;
654 int err; 653 int err;
655 654
656 *rchip = NULL;
657 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
658 if (chip == NULL) 655 if (chip == NULL)
659 return -ENOMEM; 656 return -ENOMEM;
660 chip->irq = -1; 657 chip->irq = -1;
@@ -662,25 +659,21 @@ int snd_es1688_create(struct snd_card *card,
662 659
663 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) { 660 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) {
664 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); 661 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
665 snd_es1688_free(chip);
666 return -EBUSY; 662 return -EBUSY;
667 } 663 }
668 if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) { 664 if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) {
669 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); 665 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
670 snd_es1688_free(chip);
671 return -EBUSY; 666 return -EBUSY;
672 } 667 }
673 chip->irq = irq; 668 chip->irq = irq;
674 if (request_dma(dma8, "ES1688")) { 669 if (request_dma(dma8, "ES1688")) {
675 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8); 670 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
676 snd_es1688_free(chip);
677 return -EBUSY; 671 return -EBUSY;
678 } 672 }
679 chip->dma8 = dma8; 673 chip->dma8 = dma8;
680 674
681 spin_lock_init(&chip->reg_lock); 675 spin_lock_init(&chip->reg_lock);
682 spin_lock_init(&chip->mixer_lock); 676 spin_lock_init(&chip->mixer_lock);
683 chip->card = card;
684 chip->port = port; 677 chip->port = port;
685 mpu_port &= ~0x000f; 678 mpu_port &= ~0x000f;
686 if (mpu_port < 0x300 || mpu_port > 0x330) 679 if (mpu_port < 0x300 || mpu_port > 0x330)
@@ -689,23 +682,16 @@ int snd_es1688_create(struct snd_card *card,
689 chip->mpu_irq = mpu_irq; 682 chip->mpu_irq = mpu_irq;
690 chip->hardware = hardware; 683 chip->hardware = hardware;
691 684
692 if ((err = snd_es1688_probe(chip)) < 0) { 685 err = snd_es1688_probe(chip);
693 snd_es1688_free(chip); 686 if (err < 0)
694 return err; 687 return err;
695 }
696 if ((err = snd_es1688_init(chip, 1)) < 0) {
697 snd_es1688_free(chip);
698 return err;
699 }
700 688
701 /* Register device */ 689 err = snd_es1688_init(chip, 1);
702 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 690 if (err < 0)
703 snd_es1688_free(chip);
704 return err; 691 return err;
705 }
706 692
707 *rchip = chip; 693 /* Register device */
708 return 0; 694 return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
709} 695}
710 696
711static struct snd_pcm_ops snd_es1688_playback_ops = { 697static struct snd_pcm_ops snd_es1688_playback_ops = {
@@ -730,12 +716,14 @@ static struct snd_pcm_ops snd_es1688_capture_ops = {
730 .pointer = snd_es1688_capture_pointer, 716 .pointer = snd_es1688_capture_pointer,
731}; 717};
732 718
733int snd_es1688_pcm(struct snd_es1688 * chip, int device, struct snd_pcm ** rpcm) 719int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip,
720 int device, struct snd_pcm **rpcm)
734{ 721{
735 struct snd_pcm *pcm; 722 struct snd_pcm *pcm;
736 int err; 723 int err;
737 724
738 if ((err = snd_pcm_new(chip->card, "ESx688", device, 1, 1, &pcm)) < 0) 725 err = snd_pcm_new(card, "ESx688", device, 1, 1, &pcm);
726 if (err < 0)
739 return err; 727 return err;
740 728
741 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops); 729 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops);
@@ -1009,18 +997,15 @@ static unsigned char snd_es1688_init_table[][2] = {
1009 { ES1688_REC_DEV, 0x17 } 997 { ES1688_REC_DEV, 0x17 }
1010}; 998};
1011 999
1012int snd_es1688_mixer(struct snd_es1688 *chip) 1000int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip)
1013{ 1001{
1014 struct snd_card *card;
1015 unsigned int idx; 1002 unsigned int idx;
1016 int err; 1003 int err;
1017 unsigned char reg, val; 1004 unsigned char reg, val;
1018 1005
1019 if (snd_BUG_ON(!chip || !chip->card)) 1006 if (snd_BUG_ON(!chip || !card))
1020 return -EINVAL; 1007 return -EINVAL;
1021 1008
1022 card = chip->card;
1023
1024 strcpy(card->mixername, snd_es1688_chip_id(chip)); 1009 strcpy(card->mixername, snd_es1688_chip_id(chip));
1025 1010
1026 for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) { 1011 for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) {
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index 2803e227aec9..2ccb3fadd7be 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -31,52 +31,21 @@ struct gus_proc_private {
31 struct snd_gus_card * gus; 31 struct snd_gus_card * gus;
32}; 32};
33 33
34static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_private_data, 34static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry,
35 struct file *file, char __user *buf, 35 void *file_private_data,
36 unsigned long count, unsigned long pos) 36 struct file *file, char __user *buf,
37 size_t count, loff_t pos)
37{ 38{
38 long size;
39 struct gus_proc_private *priv = entry->private_data; 39 struct gus_proc_private *priv = entry->private_data;
40 struct snd_gus_card *gus = priv->gus; 40 struct snd_gus_card *gus = priv->gus;
41 int err; 41 int err;
42 42
43 size = count; 43 err = snd_gus_dram_read(gus, buf, pos, count, priv->rom);
44 if (pos + size > priv->size) 44 if (err < 0)
45 size = (long)priv->size - pos; 45 return err;
46 if (size > 0) { 46 return count;
47 if ((err = snd_gus_dram_read(gus, buf, pos, size, priv->rom)) < 0)
48 return err;
49 return size;
50 }
51 return 0;
52} 47}
53 48
54static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry,
55 void *private_file_data,
56 struct file *file,
57 long long offset,
58 int orig)
59{
60 struct gus_proc_private *priv = entry->private_data;
61
62 switch (orig) {
63 case SEEK_SET:
64 file->f_pos = offset;
65 break;
66 case SEEK_CUR:
67 file->f_pos += offset;
68 break;
69 case SEEK_END: /* offset is negative */
70 file->f_pos = priv->size + offset;
71 break;
72 default:
73 return -EINVAL;
74 }
75 if (file->f_pos > priv->size)
76 file->f_pos = priv->size;
77 return file->f_pos;
78}
79
80static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) 49static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
81{ 50{
82 struct gus_proc_private *priv = entry->private_data; 51 struct gus_proc_private *priv = entry->private_data;
@@ -85,7 +54,6 @@ static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
85 54
86static struct snd_info_entry_ops snd_gf1_mem_proc_ops = { 55static struct snd_info_entry_ops snd_gf1_mem_proc_ops = {
87 .read = snd_gf1_mem_proc_dump, 56 .read = snd_gf1_mem_proc_dump,
88 .llseek = snd_gf1_mem_proc_llseek,
89}; 57};
90 58
91int snd_gf1_mem_proc_init(struct snd_gus_card * gus) 59int snd_gf1_mem_proc_init(struct snd_gus_card * gus)
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 65e4b18581a6..008e8e5bfa37 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -95,7 +95,7 @@ static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
95} 95}
96 96
97static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, 97static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
98 struct device *dev, unsigned int n, struct snd_es1688 **rchip) 98 struct snd_es1688 *chip, struct device *dev, unsigned int n)
99{ 99{
100 static long possible_ports[] = {0x220, 0x240, 0x260}; 100 static long possible_ports[] = {0x220, 0x240, 0x260};
101 static int possible_irqs[] = {5, 9, 10, 7, -1}; 101 static int possible_irqs[] = {5, 9, 10, 7, -1};
@@ -119,14 +119,14 @@ static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
119 } 119 }
120 120
121 if (port[n] != SNDRV_AUTO_PORT) 121 if (port[n] != SNDRV_AUTO_PORT)
122 return snd_es1688_create(card, port[n], mpu_port[n], irq[n], 122 return snd_es1688_create(card, chip, port[n], mpu_port[n],
123 mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); 123 irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
124 124
125 i = 0; 125 i = 0;
126 do { 126 do {
127 port[n] = possible_ports[i]; 127 port[n] = possible_ports[i];
128 error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], 128 error = snd_es1688_create(card, chip, port[n], mpu_port[n],
129 mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); 129 irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
130 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); 130 } while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
131 131
132 return error; 132 return error;
@@ -206,9 +206,8 @@ static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
206 return 0; 206 return 0;
207} 207}
208 208
209static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) 209static int __devinit snd_gusextreme_mixer(struct snd_card *card)
210{ 210{
211 struct snd_card *card = chip->card;
212 struct snd_ctl_elem_id id1, id2; 211 struct snd_ctl_elem_id id1, id2;
213 int error; 212 int error;
214 213
@@ -241,17 +240,20 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
241 struct snd_opl3 *opl3; 240 struct snd_opl3 *opl3;
242 int error; 241 int error;
243 242
244 error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); 243 error = snd_card_create(index[n], id[n], THIS_MODULE,
244 sizeof(struct snd_es1688), &card);
245 if (error < 0) 245 if (error < 0)
246 return error; 246 return error;
247 247
248 es1688 = card->private_data;
249
248 if (mpu_port[n] == SNDRV_AUTO_PORT) 250 if (mpu_port[n] == SNDRV_AUTO_PORT)
249 mpu_port[n] = 0; 251 mpu_port[n] = 0;
250 252
251 if (mpu_irq[n] > 15) 253 if (mpu_irq[n] > 15)
252 mpu_irq[n] = -1; 254 mpu_irq[n] = -1;
253 255
254 error = snd_gusextreme_es1688_create(card, dev, n, &es1688); 256 error = snd_gusextreme_es1688_create(card, es1688, dev, n);
255 if (error < 0) 257 if (error < 0)
256 goto out; 258 goto out;
257 259
@@ -280,11 +282,11 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
280 } 282 }
281 gus->codec_flag = 1; 283 gus->codec_flag = 1;
282 284
283 error = snd_es1688_pcm(es1688, 0, NULL); 285 error = snd_es1688_pcm(card, es1688, 0, NULL);
284 if (error < 0) 286 if (error < 0)
285 goto out; 287 goto out;
286 288
287 error = snd_es1688_mixer(es1688); 289 error = snd_es1688_mixer(card, es1688);
288 if (error < 0) 290 if (error < 0)
289 goto out; 291 goto out;
290 292
@@ -300,7 +302,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
300 if (error < 0) 302 if (error < 0)
301 goto out; 303 goto out;
302 304
303 error = snd_gusextreme_mixer(es1688); 305 error = snd_gusextreme_mixer(card);
304 if (error < 0) 306 if (error < 0)
305 goto out; 307 goto out;
306 308
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index af3669681788..08b9fb974658 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -11,7 +11,6 @@ snd-sb8-objs := sb8.o
11snd-sb16-objs := sb16.o 11snd-sb16-objs := sb16.o
12snd-sbawe-objs := sbawe.o emu8000.o 12snd-sbawe-objs := sbawe.o emu8000.o
13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o 13snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
14snd-es968-objs := es968.o
15snd-jazz16-objs := jazz16.o 14snd-jazz16-objs := jazz16.o
16 15
17# Toplevel Module Dependency 16# Toplevel Module Dependency
@@ -21,7 +20,6 @@ obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o
21obj-$(CONFIG_SND_SB8) += snd-sb8.o 20obj-$(CONFIG_SND_SB8) += snd-sb8.o
22obj-$(CONFIG_SND_SB16) += snd-sb16.o 21obj-$(CONFIG_SND_SB16) += snd-sb16.o
23obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o 22obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
24obj-$(CONFIG_SND_ES968) += snd-es968.o
25obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o 23obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
26ifeq ($(CONFIG_SND_SB16_CSP),y) 24ifeq ($(CONFIG_SND_SB16_CSP),y)
27 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o 25 obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c
deleted file mode 100644
index ff18286fef9d..000000000000
--- a/sound/isa/sb/es968.c
+++ /dev/null
@@ -1,248 +0,0 @@
1
2/*
3 card-es968.c - driver for ESS AudioDrive ES968 based soundcards.
4 Copyright (C) 1999 by Massimo Piccioni <dafastidio@libero.it>
5
6 Thanks to Pierfrancesco 'qM2' Passerini.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/init.h>
24#include <linux/time.h>
25#include <linux/pnp.h>
26#include <linux/moduleparam.h>
27#include <sound/core.h>
28#include <sound/initval.h>
29#include <sound/sb.h>
30
31#define PFX "es968: "
32
33MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
34MODULE_DESCRIPTION("ESS AudioDrive ES968");
35MODULE_LICENSE("GPL");
36MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}");
37
38static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
39static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
40static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
41static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
42static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */
43static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
44
45module_param_array(index, int, NULL, 0444);
46MODULE_PARM_DESC(index, "Index value for es968 based soundcard.");
47module_param_array(id, charp, NULL, 0444);
48MODULE_PARM_DESC(id, "ID string for es968 based soundcard.");
49module_param_array(enable, bool, NULL, 0444);
50MODULE_PARM_DESC(enable, "Enable es968 based soundcard.");
51
52struct snd_card_es968 {
53 struct pnp_dev *dev;
54 struct snd_sb *chip;
55};
56
57static struct pnp_card_device_id snd_es968_pnpids[] = {
58 { .id = "ESS0968", .devs = { { "@@@0968" }, } },
59 { .id = "", } /* end */
60};
61
62MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
63
64#define DRIVER_NAME "snd-card-es968"
65
66static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id)
67{
68 struct snd_sb *chip = dev_id;
69
70 if (chip->open & SB_OPEN_PCM) {
71 return snd_sb8dsp_interrupt(chip);
72 } else {
73 return snd_sb8dsp_midi_interrupt(chip);
74 }
75}
76
77static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
78 struct pnp_card_link *card,
79 const struct pnp_card_device_id *id)
80{
81 struct pnp_dev *pdev;
82 int err;
83
84 acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
85 if (acard->dev == NULL)
86 return -ENODEV;
87
88 pdev = acard->dev;
89
90 err = pnp_activate_dev(pdev);
91 if (err < 0) {
92 snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
93 return err;
94 }
95 port[dev] = pnp_port_start(pdev, 0);
96 dma8[dev] = pnp_dma(pdev, 0);
97 irq[dev] = pnp_irq(pdev, 0);
98
99 return 0;
100}
101
102static int __devinit snd_card_es968_probe(int dev,
103 struct pnp_card_link *pcard,
104 const struct pnp_card_device_id *pid)
105{
106 int error;
107 struct snd_sb *chip;
108 struct snd_card *card;
109 struct snd_card_es968 *acard;
110
111 error = snd_card_create(index[dev], id[dev], THIS_MODULE,
112 sizeof(struct snd_card_es968), &card);
113 if (error < 0)
114 return error;
115 acard = card->private_data;
116 if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) {
117 snd_card_free(card);
118 return error;
119 }
120 snd_card_set_dev(card, &pcard->card->dev);
121
122 if ((error = snd_sbdsp_create(card, port[dev],
123 irq[dev],
124 snd_card_es968_interrupt,
125 dma8[dev],
126 -1,
127 SB_HW_AUTO, &chip)) < 0) {
128 snd_card_free(card);
129 return error;
130 }
131 acard->chip = chip;
132
133 if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) {
134 snd_card_free(card);
135 return error;
136 }
137
138 if ((error = snd_sbmixer_new(chip)) < 0) {
139 snd_card_free(card);
140 return error;
141 }
142
143 if ((error = snd_sb8dsp_midi(chip, 0, NULL)) < 0) {
144 snd_card_free(card);
145 return error;
146 }
147
148 strcpy(card->driver, "ES968");
149 strcpy(card->shortname, "ESS ES968");
150 sprintf(card->longname, "%s soundcard, %s at 0x%lx, irq %d, dma %d",
151 card->shortname, chip->name, chip->port, irq[dev], dma8[dev]);
152
153 if ((error = snd_card_register(card)) < 0) {
154 snd_card_free(card);
155 return error;
156 }
157 pnp_set_card_drvdata(pcard, card);
158 return 0;
159}
160
161static unsigned int __devinitdata es968_devices;
162
163static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card,
164 const struct pnp_card_device_id *id)
165{
166 static int dev;
167 int res;
168
169 for ( ; dev < SNDRV_CARDS; dev++) {
170 if (!enable[dev])
171 continue;
172 res = snd_card_es968_probe(dev, card, id);
173 if (res < 0)
174 return res;
175 dev++;
176 es968_devices++;
177 return 0;
178 }
179 return -ENODEV;
180}
181
182static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
183{
184 snd_card_free(pnp_get_card_drvdata(pcard));
185 pnp_set_card_drvdata(pcard, NULL);
186}
187
188#ifdef CONFIG_PM
189static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
190{
191 struct snd_card *card = pnp_get_card_drvdata(pcard);
192 struct snd_card_es968 *acard = card->private_data;
193 struct snd_sb *chip = acard->chip;
194
195 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
196 snd_pcm_suspend_all(chip->pcm);
197 snd_sbmixer_suspend(chip);
198 return 0;
199}
200
201static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
202{
203 struct snd_card *card = pnp_get_card_drvdata(pcard);
204 struct snd_card_es968 *acard = card->private_data;
205 struct snd_sb *chip = acard->chip;
206
207 snd_sbdsp_reset(chip);
208 snd_sbmixer_resume(chip);
209 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
210 return 0;
211}
212#endif
213
214static struct pnp_card_driver es968_pnpc_driver = {
215 .flags = PNP_DRIVER_RES_DISABLE,
216 .name = "es968",
217 .id_table = snd_es968_pnpids,
218 .probe = snd_es968_pnp_detect,
219 .remove = __devexit_p(snd_es968_pnp_remove),
220#ifdef CONFIG_PM
221 .suspend = snd_es968_pnp_suspend,
222 .resume = snd_es968_pnp_resume,
223#endif
224};
225
226static int __init alsa_card_es968_init(void)
227{
228 int err = pnp_register_card_driver(&es968_pnpc_driver);
229 if (err)
230 return err;
231
232 if (!es968_devices) {
233 pnp_unregister_card_driver(&es968_pnpc_driver);
234#ifdef MODULE
235 snd_printk(KERN_ERR "no ES968 based soundcards found\n");
236#endif
237 return -ENODEV;
238 }
239 return 0;
240}
241
242static void __exit alsa_card_es968_exit(void)
243{
244 pnp_unregister_card_driver(&es968_pnpc_driver);
245}
246
247module_init(alsa_card_es968_init)
248module_exit(alsa_card_es968_exit)
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index bb14e4c67e89..87910e992133 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -21,6 +21,7 @@
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22#include <linux/soundcard.h> 22#include <linux/soundcard.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26#include <asm/setup.h> 27#include <asm/setup.h>
@@ -710,31 +711,41 @@ static MACHINE machAmiga = {
710/*** Config & Setup **********************************************************/ 711/*** Config & Setup **********************************************************/
711 712
712 713
713static int __init dmasound_paula_init(void) 714static int __init amiga_audio_probe(struct platform_device *pdev)
714{ 715{
715 int err; 716 dmasound.mach = machAmiga;
716 717 dmasound.mach.default_hard = def_hard ;
717 if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_AUDIO)) { 718 dmasound.mach.default_soft = def_soft ;
718 if (!request_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40, 719 return dmasound_init();
719 "dmasound [Paula]"))
720 return -EBUSY;
721 dmasound.mach = machAmiga;
722 dmasound.mach.default_hard = def_hard ;
723 dmasound.mach.default_soft = def_soft ;
724 err = dmasound_init();
725 if (err)
726 release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40);
727 return err;
728 } else
729 return -ENODEV;
730} 720}
731 721
732static void __exit dmasound_paula_cleanup(void) 722static int __exit amiga_audio_remove(struct platform_device *pdev)
733{ 723{
734 dmasound_deinit(); 724 dmasound_deinit();
735 release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40); 725 return 0;
726}
727
728static struct platform_driver amiga_audio_driver = {
729 .remove = __exit_p(amiga_audio_remove),
730 .driver = {
731 .name = "amiga-audio",
732 .owner = THIS_MODULE,
733 },
734};
735
736static int __init amiga_audio_init(void)
737{
738 return platform_driver_probe(&amiga_audio_driver, amiga_audio_probe);
736} 739}
737 740
738module_init(dmasound_paula_init); 741module_init(amiga_audio_init);
739module_exit(dmasound_paula_cleanup); 742
743static void __exit amiga_audio_exit(void)
744{
745 platform_driver_unregister(&amiga_audio_driver);
746}
747
748module_exit(amiga_audio_exit);
749
740MODULE_LICENSE("GPL"); 750MODULE_LICENSE("GPL");
751MODULE_ALIAS("platform:amiga-audio");
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 1298c68d6bf0..e7a8cd058efb 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -58,6 +58,18 @@ config SND_ALI5451
58 To compile this driver as a module, choose M here: the module 58 To compile this driver as a module, choose M here: the module
59 will be called snd-ali5451. 59 will be called snd-ali5451.
60 60
61config SND_ASIHPI
62 tristate "AudioScience ASIxxxx"
63 depends on X86
64 select FW_LOADER
65 select SND_PCM
66 select SND_HWDEP
67 help
68 Say Y here to include support for AudioScience ASI sound cards.
69
70 To compile this driver as a module, choose M here: the module
71 will be called snd-asihpi.
72
61config SND_ATIIXP 73config SND_ATIIXP
62 tristate "ATI IXP AC97 Controller" 74 tristate "ATI IXP AC97 Controller"
63 select SND_AC97_CODEC 75 select SND_AC97_CODEC
@@ -501,6 +513,16 @@ config SND_ES1968
501 To compile this driver as a module, choose M here: the module 513 To compile this driver as a module, choose M here: the module
502 will be called snd-es1968. 514 will be called snd-es1968.
503 515
516config SND_ES1968_INPUT
517 bool "Enable input device for es1968 volume buttons"
518 depends on SND_ES1968
519 depends on INPUT=y || INPUT=SND_ES1968
520 help
521 If you say Y here, you will get an input device which reports
522 keypresses for the volume buttons connected to the es1968 chip.
523 If you say N the buttons will directly control the master volume.
524 It is recommended to say Y.
525
504config SND_FM801 526config SND_FM801
505 tristate "ForteMedia FM801" 527 tristate "ForteMedia FM801"
506 select SND_OPL3_LIB 528 select SND_OPL3_LIB
@@ -655,6 +677,16 @@ config SND_MAESTRO3
655 To compile this driver as a module, choose M here: the module 677 To compile this driver as a module, choose M here: the module
656 will be called snd-maestro3. 678 will be called snd-maestro3.
657 679
680config SND_MAESTRO3_INPUT
681 bool "Enable input device for maestro3 volume buttons"
682 depends on SND_MAESTRO3
683 depends on INPUT=y || INPUT=SND_MAESTRO3
684 help
685 If you say Y here, you will get an input device which reports
686 keypresses for the volume buttons connected to the maestro3 chip.
687 If you say N the buttons will directly control the master volume.
688 It is recommended to say Y.
689
658config SND_MIXART 690config SND_MIXART
659 tristate "Digigram miXart" 691 tristate "Digigram miXart"
660 select SND_HWDEP 692 select SND_HWDEP
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index ecfc609d2b9f..9cf4348ec137 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
57obj-$(CONFIG_SND) += \ 57obj-$(CONFIG_SND) += \
58 ac97/ \ 58 ac97/ \
59 ali5451/ \ 59 ali5451/ \
60 asihpi/ \
60 au88x0/ \ 61 au88x0/ \
61 aw2/ \ 62 aw2/ \
62 ctxfi/ \ 63 ctxfi/ \
diff --git a/sound/pci/asihpi/Makefile b/sound/pci/asihpi/Makefile
new file mode 100644
index 000000000000..391830a4556c
--- /dev/null
+++ b/sound/pci/asihpi/Makefile
@@ -0,0 +1,5 @@
1snd-asihpi-objs := asihpi.o hpioctl.o hpimsginit.o\
2 hpicmn.o hpifunc.o hpidebug.o hpidspcd.o\
3 hpios.o hpi6000.o hpi6205.o hpimsgx.o
4
5obj-$(CONFIG_SND_ASIHPI) += snd-asihpi.o
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
new file mode 100644
index 000000000000..f74c7372b3d1
--- /dev/null
+++ b/sound/pci/asihpi/asihpi.c
@@ -0,0 +1,3002 @@
1/*
2 * Asihpi soundcard
3 * Copyright (c) by AudioScience Inc <alsa@audioscience.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 *
19 * The following is not a condition of use, merely a request:
20 * If you modify this program, particularly if you fix errors, AudioScience Inc
21 * would appreciate it if you grant us the right to use those modifications
22 * for any purpose including commercial applications.
23 */
24/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */
25#define REALLY_VERBOSE_LOGGING 0
26
27#if REALLY_VERBOSE_LOGGING
28#define VPRINTK1 snd_printd
29#else
30#define VPRINTK1(...)
31#endif
32
33#if REALLY_VERBOSE_LOGGING > 1
34#define VPRINTK2 snd_printd
35#else
36#define VPRINTK2(...)
37#endif
38
39#ifndef ASI_STYLE_NAMES
40/* not sure how ALSA style name should look */
41#define ASI_STYLE_NAMES 1
42#endif
43
44#include "hpi_internal.h"
45#include "hpimsginit.h"
46#include "hpioctl.h"
47
48#include <linux/pci.h>
49#include <linux/init.h>
50#include <linux/jiffies.h>
51#include <linux/slab.h>
52#include <linux/time.h>
53#include <linux/wait.h>
54#include <sound/core.h>
55#include <sound/control.h>
56#include <sound/pcm.h>
57#include <sound/pcm_params.h>
58#include <sound/info.h>
59#include <sound/initval.h>
60#include <sound/tlv.h>
61#include <sound/hwdep.h>
62
63
64MODULE_LICENSE("GPL");
65MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
66MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
67
68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */
69static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
70static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
71static int enable_hpi_hwdep = 1;
72
73module_param_array(index, int, NULL, S_IRUGO);
74MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
75
76module_param_array(id, charp, NULL, S_IRUGO);
77MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
78
79module_param_array(enable, bool, NULL, S_IRUGO);
80MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
81
82module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
83MODULE_PARM_DESC(enable_hpi_hwdep,
84 "ALSA enable HPI hwdep for AudioScience soundcard ");
85
86/* identify driver */
87#ifdef KERNEL_ALSA_BUILD
88static char *build_info = "built using headers from kernel source";
89module_param(build_info, charp, S_IRUGO);
90MODULE_PARM_DESC(build_info, "built using headers from kernel source");
91#else
92static char *build_info = "built within ALSA source";
93module_param(build_info, charp, S_IRUGO);
94MODULE_PARM_DESC(build_info, "built within ALSA source");
95#endif
96
97/* set to 1 to dump every control from adapter to log */
98static const int mixer_dump;
99
100#define DEFAULT_SAMPLERATE 44100
101static int adapter_fs = DEFAULT_SAMPLERATE;
102
103static struct hpi_hsubsys *ss; /* handle to HPI audio subsystem */
104
105/* defaults */
106#define PERIODS_MIN 2
107#define PERIOD_BYTES_MIN 2304
108#define BUFFER_BYTES_MAX (512 * 1024)
109
110/*#define TIMER_MILLISECONDS 20
111#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
112*/
113
114#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
115
116struct clk_source {
117 int source;
118 int index;
119 char *name;
120};
121
122struct clk_cache {
123 int count;
124 int has_local;
125 struct clk_source s[MAX_CLOCKSOURCES];
126};
127
128/* Per card data */
129struct snd_card_asihpi {
130 struct snd_card *card;
131 struct pci_dev *pci;
132 u16 adapter_index;
133 u32 serial_number;
134 u16 type;
135 u16 version;
136 u16 num_outstreams;
137 u16 num_instreams;
138
139 u32 h_mixer;
140 struct clk_cache cc;
141
142 u16 support_mmap;
143 u16 support_grouping;
144 u16 support_mrx;
145 u16 update_interval_frames;
146 u16 in_max_chans;
147 u16 out_max_chans;
148};
149
150/* Per stream data */
151struct snd_card_asihpi_pcm {
152 struct timer_list timer;
153 unsigned int respawn_timer;
154 unsigned int hpi_buffer_attached;
155 unsigned int pcm_size;
156 unsigned int pcm_count;
157 unsigned int bytes_per_sec;
158 unsigned int pcm_irq_pos; /* IRQ position */
159 unsigned int pcm_buf_pos; /* position in buffer */
160 struct snd_pcm_substream *substream;
161 u32 h_stream;
162 struct hpi_format format;
163};
164
165/* universal stream verbs work with out or in stream handles */
166
167/* Functions to allow driver to give a buffer to HPI for busmastering */
168
169static u16 hpi_stream_host_buffer_attach(
170 struct hpi_hsubsys *hS,
171 u32 h_stream, /* handle to outstream. */
172 u32 size_in_bytes, /* size in bytes of bus mastering buffer */
173 u32 pci_address
174)
175{
176 struct hpi_message hm;
177 struct hpi_response hr;
178 unsigned int obj = hpi_handle_object(h_stream);
179
180 if (!h_stream)
181 return HPI_ERROR_INVALID_OBJ;
182 hpi_init_message_response(&hm, &hr, obj,
183 obj == HPI_OBJ_OSTREAM ?
184 HPI_OSTREAM_HOSTBUFFER_ALLOC :
185 HPI_ISTREAM_HOSTBUFFER_ALLOC);
186
187 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
188 &hm.obj_index);
189
190 hm.u.d.u.buffer.buffer_size = size_in_bytes;
191 hm.u.d.u.buffer.pci_address = pci_address;
192 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
193 hpi_send_recv(&hm, &hr);
194 return hr.error;
195}
196
197static u16 hpi_stream_host_buffer_detach(
198 struct hpi_hsubsys *hS,
199 u32 h_stream
200)
201{
202 struct hpi_message hm;
203 struct hpi_response hr;
204 unsigned int obj = hpi_handle_object(h_stream);
205
206 if (!h_stream)
207 return HPI_ERROR_INVALID_OBJ;
208
209 hpi_init_message_response(&hm, &hr, obj,
210 obj == HPI_OBJ_OSTREAM ?
211 HPI_OSTREAM_HOSTBUFFER_FREE :
212 HPI_ISTREAM_HOSTBUFFER_FREE);
213
214 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
215 &hm.obj_index);
216 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
217 hpi_send_recv(&hm, &hr);
218 return hr.error;
219}
220
221static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream)
222{
223 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
224 return hpi_outstream_start(hS, h_stream);
225 else
226 return hpi_instream_start(hS, h_stream);
227}
228
229static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream)
230{
231 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
232 return hpi_outstream_stop(hS, h_stream);
233 else
234 return hpi_instream_stop(hS, h_stream);
235}
236
237static inline u16 hpi_stream_get_info_ex(
238 struct hpi_hsubsys *hS,
239 u32 h_stream,
240 u16 *pw_state,
241 u32 *pbuffer_size,
242 u32 *pdata_in_buffer,
243 u32 *psample_count,
244 u32 *pauxiliary_data
245)
246{
247 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
248 return hpi_outstream_get_info_ex(hS, h_stream, pw_state,
249 pbuffer_size, pdata_in_buffer,
250 psample_count, pauxiliary_data);
251 else
252 return hpi_instream_get_info_ex(hS, h_stream, pw_state,
253 pbuffer_size, pdata_in_buffer,
254 psample_count, pauxiliary_data);
255}
256
257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS,
258 u32 h_master,
259 u32 h_stream)
260{
261 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
262 return hpi_outstream_group_add(hS, h_master, h_stream);
263 else
264 return hpi_instream_group_add(hS, h_master, h_stream);
265}
266
267static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS,
268 u32 h_stream)
269{
270 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
271 return hpi_outstream_group_reset(hS, h_stream);
272 else
273 return hpi_instream_group_reset(hS, h_stream);
274}
275
276static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS,
277 u32 h_stream, u32 *mo, u32 *mi)
278{
279 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
280 return hpi_outstream_group_get_map(hS, h_stream, mo, mi);
281 else
282 return hpi_instream_group_get_map(hS, h_stream, mo, mi);
283}
284
285static u16 handle_error(u16 err, int line, char *filename)
286{
287 if (err)
288 printk(KERN_WARNING
289 "in file %s, line %d: HPI error %d\n",
290 filename, line, err);
291 return err;
292}
293
294#define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
295
296/***************************** GENERAL PCM ****************/
297#if REALLY_VERBOSE_LOGGING
298static void print_hwparams(struct snd_pcm_hw_params *p)
299{
300 snd_printd("HWPARAMS \n");
301 snd_printd("samplerate %d \n", params_rate(p));
302 snd_printd("channels %d \n", params_channels(p));
303 snd_printd("format %d \n", params_format(p));
304 snd_printd("subformat %d \n", params_subformat(p));
305 snd_printd("buffer bytes %d \n", params_buffer_bytes(p));
306 snd_printd("period bytes %d \n", params_period_bytes(p));
307 snd_printd("access %d \n", params_access(p));
308 snd_printd("period_size %d \n", params_period_size(p));
309 snd_printd("periods %d \n", params_periods(p));
310 snd_printd("buffer_size %d \n", params_buffer_size(p));
311}
312#else
313#define print_hwparams(x)
314#endif
315
316static snd_pcm_format_t hpi_to_alsa_formats[] = {
317 -1, /* INVALID */
318 SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
319 SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
320 -1, /* HPI_FORMAT_MPEG_L1 3 */
321 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
322 SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
323 -1, /* HPI_FORMAT_DOLBY_AC2 6 */
324 -1, /* HPI_FORMAT_DOLBY_AC3 7 */
325 SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
326 -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
327 -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
328 SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
329 -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
330 -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
331 SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
332#if 1
333 /* ALSA can't handle 3 byte sample size together with power-of-2
334 * constraint on buffer_bytes, so disable this format
335 */
336 -1
337#else
338 /* SNDRV_PCM_FORMAT_S24_3LE */ /* { HPI_FORMAT_PCM24_SIGNED 15 */
339#endif
340};
341
342
343static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
344 u16 *hpi_format)
345{
346 u16 format;
347
348 for (format = HPI_FORMAT_PCM8_UNSIGNED;
349 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
350 if (hpi_to_alsa_formats[format] == alsa_format) {
351 *hpi_format = format;
352 return 0;
353 }
354 }
355
356 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
357 alsa_format);
358 *hpi_format = 0;
359 return -EINVAL;
360}
361
362static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
363 struct snd_pcm_hardware *pcmhw)
364{
365 u16 err;
366 u32 h_control;
367 u32 sample_rate;
368 int idx;
369 unsigned int rate_min = 200000;
370 unsigned int rate_max = 0;
371 unsigned int rates = 0;
372
373 if (asihpi->support_mrx) {
374 rates |= SNDRV_PCM_RATE_CONTINUOUS;
375 rates |= SNDRV_PCM_RATE_8000_96000;
376 rate_min = 8000;
377 rate_max = 100000;
378 } else {
379 /* on cards without SRC,
380 valid rates are determined by sampleclock */
381 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
382 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
383 HPI_CONTROL_SAMPLECLOCK, &h_control);
384 if (err) {
385 snd_printk(KERN_ERR
386 "no local sampleclock, err %d\n", err);
387 }
388
389 for (idx = 0; idx < 100; idx++) {
390 if (hpi_sample_clock_query_local_rate(ss,
391 h_control, idx, &sample_rate)) {
392 if (!idx)
393 snd_printk(KERN_ERR
394 "local rate query failed\n");
395
396 break;
397 }
398
399 rate_min = min(rate_min, sample_rate);
400 rate_max = max(rate_max, sample_rate);
401
402 switch (sample_rate) {
403 case 5512:
404 rates |= SNDRV_PCM_RATE_5512;
405 break;
406 case 8000:
407 rates |= SNDRV_PCM_RATE_8000;
408 break;
409 case 11025:
410 rates |= SNDRV_PCM_RATE_11025;
411 break;
412 case 16000:
413 rates |= SNDRV_PCM_RATE_16000;
414 break;
415 case 22050:
416 rates |= SNDRV_PCM_RATE_22050;
417 break;
418 case 32000:
419 rates |= SNDRV_PCM_RATE_32000;
420 break;
421 case 44100:
422 rates |= SNDRV_PCM_RATE_44100;
423 break;
424 case 48000:
425 rates |= SNDRV_PCM_RATE_48000;
426 break;
427 case 64000:
428 rates |= SNDRV_PCM_RATE_64000;
429 break;
430 case 88200:
431 rates |= SNDRV_PCM_RATE_88200;
432 break;
433 case 96000:
434 rates |= SNDRV_PCM_RATE_96000;
435 break;
436 case 176400:
437 rates |= SNDRV_PCM_RATE_176400;
438 break;
439 case 192000:
440 rates |= SNDRV_PCM_RATE_192000;
441 break;
442 default: /* some other rate */
443 rates |= SNDRV_PCM_RATE_KNOT;
444 }
445 }
446 }
447
448 /* printk(KERN_INFO "Supported rates %X %d %d\n",
449 rates, rate_min, rate_max); */
450 pcmhw->rates = rates;
451 pcmhw->rate_min = rate_min;
452 pcmhw->rate_max = rate_max;
453}
454
455static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
456 struct snd_pcm_hw_params *params)
457{
458 struct snd_pcm_runtime *runtime = substream->runtime;
459 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
460 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
461 int err;
462 u16 format;
463 unsigned int bytes_per_sec;
464
465 print_hwparams(params);
466 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
467 if (err < 0)
468 return err;
469 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
470 if (err)
471 return err;
472
473 VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n",
474 format, params_channels(params),
475 params_rate(params));
476
477 hpi_handle_error(hpi_format_create(&dpcm->format,
478 params_channels(params),
479 format, params_rate(params), 0, 0));
480
481 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
482 if (hpi_instream_reset(ss, dpcm->h_stream) != 0)
483 return -EINVAL;
484
485 if (hpi_instream_set_format(ss,
486 dpcm->h_stream, &dpcm->format) != 0)
487 return -EINVAL;
488 }
489
490 dpcm->hpi_buffer_attached = 0;
491 if (card->support_mmap) {
492
493 err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream,
494 params_buffer_bytes(params), runtime->dma_addr);
495 if (err == 0) {
496 snd_printd(KERN_INFO
497 "stream_host_buffer_attach succeeded %u %lu\n",
498 params_buffer_bytes(params),
499 (unsigned long)runtime->dma_addr);
500 } else {
501 snd_printd(KERN_INFO
502 "stream_host_buffer_attach error %d\n",
503 err);
504 return -ENOMEM;
505 }
506
507 err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL,
508 &dpcm->hpi_buffer_attached,
509 NULL, NULL, NULL);
510
511 snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n",
512 dpcm->hpi_buffer_attached);
513 }
514 bytes_per_sec = params_rate(params) * params_channels(params);
515 bytes_per_sec *= snd_pcm_format_width(params_format(params));
516 bytes_per_sec /= 8;
517 if (bytes_per_sec <= 0)
518 return -EINVAL;
519
520 dpcm->bytes_per_sec = bytes_per_sec;
521 dpcm->pcm_size = params_buffer_bytes(params);
522 dpcm->pcm_count = params_period_bytes(params);
523 snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n",
524 dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec);
525
526 dpcm->pcm_irq_pos = 0;
527 dpcm->pcm_buf_pos = 0;
528 return 0;
529}
530
531static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
532 substream)
533{
534 struct snd_pcm_runtime *runtime = substream->runtime;
535 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
536 int expiry;
537
538 expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec);
539 /* wait longer the first time, for samples to propagate */
540 expiry = max(expiry, 20);
541 dpcm->timer.expires = jiffies + expiry;
542 dpcm->respawn_timer = 1;
543 add_timer(&dpcm->timer);
544}
545
546static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
547{
548 struct snd_pcm_runtime *runtime = substream->runtime;
549 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
550
551 dpcm->respawn_timer = 0;
552 del_timer(&dpcm->timer);
553}
554
555static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
556 int cmd)
557{
558 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
559 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
560 struct snd_pcm_substream *s;
561 u16 e;
562
563 snd_printd("trigger %dstream %d\n",
564 substream->stream, substream->number);
565 switch (cmd) {
566 case SNDRV_PCM_TRIGGER_START:
567 snd_pcm_group_for_each_entry(s, substream) {
568 struct snd_card_asihpi_pcm *ds;
569 ds = s->runtime->private_data;
570
571 if (snd_pcm_substream_chip(s) != card)
572 continue;
573
574 if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
575 (card->support_mmap)) {
576 /* How do I know how much valid data is present
577 * in buffer? Just guessing 2 periods, but if
578 * buffer is bigger it may contain even more
579 * data??
580 */
581 unsigned int preload = ds->pcm_count * 2;
582 VPRINTK2("preload %d\n", preload);
583 hpi_handle_error(hpi_outstream_write_buf(
584 ss, ds->h_stream,
585 &s->runtime->dma_area[0],
586 preload,
587 &ds->format));
588 }
589
590 if (card->support_grouping) {
591 VPRINTK1("\t_group %dstream %d\n", s->stream,
592 s->number);
593 e = hpi_stream_group_add(ss,
594 dpcm->h_stream,
595 ds->h_stream);
596 if (!e) {
597 snd_pcm_trigger_done(s, substream);
598 } else {
599 hpi_handle_error(e);
600 break;
601 }
602 } else
603 break;
604 }
605 snd_printd("start\n");
606 /* start the master stream */
607 snd_card_asihpi_pcm_timer_start(substream);
608 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
609 break;
610
611 case SNDRV_PCM_TRIGGER_STOP:
612 snd_card_asihpi_pcm_timer_stop(substream);
613 snd_pcm_group_for_each_entry(s, substream) {
614 if (snd_pcm_substream_chip(s) != card)
615 continue;
616
617 /*? workaround linked streams don't
618 transition to SETUP 20070706*/
619 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
620
621 if (card->support_grouping) {
622 VPRINTK1("\t_group %dstream %d\n", s->stream,
623 s->number);
624 snd_pcm_trigger_done(s, substream);
625 } else
626 break;
627 }
628 snd_printd("stop\n");
629
630 /* _prepare and _hwparams reset the stream */
631 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
632 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
633 hpi_handle_error(
634 hpi_outstream_reset(ss, dpcm->h_stream));
635
636 if (card->support_grouping)
637 hpi_handle_error(hpi_stream_group_reset(ss,
638 dpcm->h_stream));
639 break;
640
641 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
642 snd_printd("pause release\n");
643 hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
644 snd_card_asihpi_pcm_timer_start(substream);
645 break;
646 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
647 snd_printd("pause\n");
648 snd_card_asihpi_pcm_timer_stop(substream);
649 hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
650 break;
651 default:
652 snd_printd("\tINVALID\n");
653 return -EINVAL;
654 }
655
656 return 0;
657}
658
659static int
660snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
661{
662 struct snd_pcm_runtime *runtime = substream->runtime;
663 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
664 if (dpcm->hpi_buffer_attached)
665 hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
666
667 snd_pcm_lib_free_pages(substream);
668 return 0;
669}
670
671static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
672{
673 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
674 kfree(dpcm);
675}
676
677/*algorithm outline
678 Without linking degenerates to getting single stream pos etc
679 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
680*/
681/*
682buf_pos=get_buf_pos(s);
683for_each_linked_stream(s) {
684 buf_pos=get_buf_pos(s);
685 min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size)
686 new_data = min(new_data, calc_new_data(buf_pos,irq_pos)
687}
688timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
689for_each_linked_stream(s) {
690 s->buf_pos = min_buf_pos;
691 if (new_data > pcm_count) {
692 if (mmap) {
693 irq_pos = (irq_pos + pcm_count) % pcm_size;
694 if (playback) {
695 write(pcm_count);
696 } else {
697 read(pcm_count);
698 }
699 }
700 snd_pcm_period_elapsed(s);
701 }
702}
703*/
704
705/** Minimum of 2 modulo values. Works correctly when the difference between
706* the values is less than half the modulus
707*/
708static inline unsigned int modulo_min(unsigned int a, unsigned int b,
709 unsigned long int modulus)
710{
711 unsigned int result;
712 if (((a-b) % modulus) < (modulus/2))
713 result = b;
714 else
715 result = a;
716
717 return result;
718}
719
720/** Timer function, equivalent to interrupt service routine for cards
721*/
722static void snd_card_asihpi_timer_function(unsigned long data)
723{
724 struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
725 struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream);
726 struct snd_pcm_runtime *runtime;
727 struct snd_pcm_substream *s;
728 unsigned int newdata = 0;
729 unsigned int buf_pos, min_buf_pos = 0;
730 unsigned int remdata, xfercount, next_jiffies;
731 int first = 1;
732 u16 state;
733 u32 buffer_size, data_avail, samples_played, aux;
734
735 /* find minimum newdata and buffer pos in group */
736 snd_pcm_group_for_each_entry(s, dpcm->substream) {
737 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
738 runtime = s->runtime;
739
740 if (snd_pcm_substream_chip(s) != card)
741 continue;
742
743 hpi_handle_error(hpi_stream_get_info_ex(ss,
744 ds->h_stream, &state,
745 &buffer_size, &data_avail,
746 &samples_played, &aux));
747
748 /* number of bytes in on-card buffer */
749 runtime->delay = aux;
750
751 if (state == HPI_STATE_DRAINED) {
752 snd_printd(KERN_WARNING "outstream %d drained\n",
753 s->number);
754 snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
755 return;
756 }
757
758 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
759 buf_pos = frames_to_bytes(runtime, samples_played);
760 } else {
761 buf_pos = data_avail + ds->pcm_irq_pos;
762 }
763
764 if (first) {
765 /* can't statically init min when wrap is involved */
766 min_buf_pos = buf_pos;
767 newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size;
768 first = 0;
769 } else {
770 min_buf_pos =
771 modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L);
772 newdata = min(
773 (buf_pos - ds->pcm_irq_pos) % ds->pcm_size,
774 newdata);
775 }
776
777 VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n",
778 (unsigned long)frames_to_bytes(runtime,
779 runtime->status->hw_ptr),
780 (unsigned long)frames_to_bytes(runtime,
781 runtime->control->appl_ptr));
782 VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X,"
783 " aux=x%04X space=x%04X\n", s->number,
784 state, ds->pcm_irq_pos, buf_pos, (int)data_avail,
785 (int)aux, buffer_size-data_avail);
786 }
787
788 remdata = newdata % dpcm->pcm_count;
789 xfercount = newdata - remdata; /* a multiple of pcm_count */
790 next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1;
791 next_jiffies = max(next_jiffies, 2U * HZ / 1000U);
792 dpcm->timer.expires = jiffies + next_jiffies;
793 VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n",
794 next_jiffies, min_buf_pos, newdata, xfercount);
795
796 snd_pcm_group_for_each_entry(s, dpcm->substream) {
797 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
798 ds->pcm_buf_pos = min_buf_pos;
799
800 if (xfercount) {
801 if (card->support_mmap) {
802 ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount;
803 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
804 VPRINTK2("write OS%d x%04x\n",
805 s->number,
806 ds->pcm_count);
807 hpi_handle_error(
808 hpi_outstream_write_buf(
809 ss, ds->h_stream,
810 &s->runtime->
811 dma_area[0],
812 xfercount,
813 &ds->format));
814 } else {
815 VPRINTK2("read IS%d x%04x\n",
816 s->number,
817 dpcm->pcm_count);
818 hpi_handle_error(
819 hpi_instream_read_buf(
820 ss, ds->h_stream,
821 NULL, xfercount));
822 }
823 } /* else R/W will be handled by read/write callbacks */
824 snd_pcm_period_elapsed(s);
825 }
826 }
827
828 if (dpcm->respawn_timer)
829 add_timer(&dpcm->timer);
830}
831
832/***************************** PLAYBACK OPS ****************/
833static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
834 unsigned int cmd, void *arg)
835{
836 /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */
837 return snd_pcm_lib_ioctl(substream, cmd, arg);
838}
839
840static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
841 substream)
842{
843 struct snd_pcm_runtime *runtime = substream->runtime;
844 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
845
846 snd_printd(KERN_INFO "playback prepare %d\n", substream->number);
847
848 hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
849 dpcm->pcm_irq_pos = 0;
850 dpcm->pcm_buf_pos = 0;
851
852 return 0;
853}
854
855static snd_pcm_uframes_t
856snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
857{
858 struct snd_pcm_runtime *runtime = substream->runtime;
859 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
860 snd_pcm_uframes_t ptr;
861
862 u32 samples_played;
863 u16 err;
864
865 if (!snd_pcm_stream_linked(substream)) {
866 /* NOTE, can use samples played for playback position here and
867 * in timer fn because it LAGS the actual read pointer, and is a
868 * better representation of actual playout position
869 */
870 err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
871 NULL, NULL,
872 &samples_played, NULL);
873 hpi_handle_error(err);
874
875 dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
876 }
877 /* else must return most conservative value found in timer func
878 * by looping over all streams
879 */
880
881 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
882 VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
883 return ptr;
884}
885
886static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
887 u32 h_stream,
888 struct snd_pcm_hardware *pcmhw)
889{
890 struct hpi_format hpi_format;
891 u16 format;
892 u16 err;
893 u32 h_control;
894 u32 sample_rate = 48000;
895
896 /* on cards without SRC, must query at valid rate,
897 * maybe set by external sync
898 */
899 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
900 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
901 HPI_CONTROL_SAMPLECLOCK, &h_control);
902
903 if (!err)
904 err = hpi_sample_clock_get_sample_rate(ss, h_control,
905 &sample_rate);
906
907 for (format = HPI_FORMAT_PCM8_UNSIGNED;
908 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
909 err = hpi_format_create(&hpi_format,
910 2, format, sample_rate, 128000, 0);
911 if (!err)
912 err = hpi_outstream_query_format(ss, h_stream,
913 &hpi_format);
914 if (!err && (hpi_to_alsa_formats[format] != -1))
915 pcmhw->formats |=
916 (1ULL << hpi_to_alsa_formats[format]);
917 }
918}
919
920static struct snd_pcm_hardware snd_card_asihpi_playback = {
921 .channels_min = 1,
922 .channels_max = 2,
923 .buffer_bytes_max = BUFFER_BYTES_MAX,
924 .period_bytes_min = PERIOD_BYTES_MIN,
925 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
926 .periods_min = PERIODS_MIN,
927 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
928 .fifo_size = 0,
929};
930
931static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
932{
933 struct snd_pcm_runtime *runtime = substream->runtime;
934 struct snd_card_asihpi_pcm *dpcm;
935 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
936 int err;
937
938 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
939 if (dpcm == NULL)
940 return -ENOMEM;
941
942 err =
943 hpi_outstream_open(ss, card->adapter_index,
944 substream->number, &dpcm->h_stream);
945 hpi_handle_error(err);
946 if (err)
947 kfree(dpcm);
948 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
949 return -EBUSY;
950 if (err)
951 return -EIO;
952
953 /*? also check ASI5000 samplerate source
954 If external, only support external rate.
955 If internal and other stream playing, cant switch
956 */
957
958 init_timer(&dpcm->timer);
959 dpcm->timer.data = (unsigned long) dpcm;
960 dpcm->timer.function = snd_card_asihpi_timer_function;
961 dpcm->substream = substream;
962 runtime->private_data = dpcm;
963 runtime->private_free = snd_card_asihpi_runtime_free;
964
965 snd_card_asihpi_playback.channels_max = card->out_max_chans;
966 /*?snd_card_asihpi_playback.period_bytes_min =
967 card->out_max_chans * 4096; */
968
969 snd_card_asihpi_playback_format(card, dpcm->h_stream,
970 &snd_card_asihpi_playback);
971
972 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
973
974 snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
975 SNDRV_PCM_INFO_DOUBLE |
976 SNDRV_PCM_INFO_BATCH |
977 SNDRV_PCM_INFO_BLOCK_TRANSFER |
978 SNDRV_PCM_INFO_PAUSE;
979
980 if (card->support_mmap)
981 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
982 SNDRV_PCM_INFO_MMAP_VALID;
983
984 if (card->support_grouping)
985 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
986
987 /* struct is copied, so can create initializer dynamically */
988 runtime->hw = snd_card_asihpi_playback;
989
990 if (card->support_mmap)
991 err = snd_pcm_hw_constraint_pow2(runtime, 0,
992 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
993 if (err < 0)
994 return err;
995
996 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
997 card->update_interval_frames);
998 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
999 card->update_interval_frames * 4, UINT_MAX);
1000
1001 snd_pcm_set_sync(substream);
1002
1003 snd_printd(KERN_INFO "playback open\n");
1004
1005 return 0;
1006}
1007
1008static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1009{
1010 struct snd_pcm_runtime *runtime = substream->runtime;
1011 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1012
1013 hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream));
1014 snd_printd(KERN_INFO "playback close\n");
1015
1016 return 0;
1017}
1018
1019static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1020 int channel,
1021 snd_pcm_uframes_t pos,
1022 void __user *src,
1023 snd_pcm_uframes_t count)
1024{
1025 struct snd_pcm_runtime *runtime = substream->runtime;
1026 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1027 unsigned int len;
1028
1029 len = frames_to_bytes(runtime, count);
1030
1031 if (copy_from_user(runtime->dma_area, src, len))
1032 return -EFAULT;
1033
1034 VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n",
1035 substream->number, len);
1036
1037 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1038 runtime->dma_area, len, &dpcm->format));
1039
1040 return 0;
1041}
1042
1043static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1044 substream, int channel,
1045 snd_pcm_uframes_t pos,
1046 snd_pcm_uframes_t count)
1047{
1048 unsigned int len;
1049 struct snd_pcm_runtime *runtime = substream->runtime;
1050 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1051
1052 len = frames_to_bytes(runtime, count);
1053 snd_printd(KERN_INFO "playback silence %u bytes\n", len);
1054
1055 memset(runtime->dma_area, 0, len);
1056 hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1057 runtime->dma_area, len, &dpcm->format));
1058 return 0;
1059}
1060
1061static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1062 .open = snd_card_asihpi_playback_open,
1063 .close = snd_card_asihpi_playback_close,
1064 .ioctl = snd_card_asihpi_playback_ioctl,
1065 .hw_params = snd_card_asihpi_pcm_hw_params,
1066 .hw_free = snd_card_asihpi_hw_free,
1067 .prepare = snd_card_asihpi_playback_prepare,
1068 .trigger = snd_card_asihpi_trigger,
1069 .pointer = snd_card_asihpi_playback_pointer,
1070 .copy = snd_card_asihpi_playback_copy,
1071 .silence = snd_card_asihpi_playback_silence,
1072};
1073
1074static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1075 .open = snd_card_asihpi_playback_open,
1076 .close = snd_card_asihpi_playback_close,
1077 .ioctl = snd_card_asihpi_playback_ioctl,
1078 .hw_params = snd_card_asihpi_pcm_hw_params,
1079 .hw_free = snd_card_asihpi_hw_free,
1080 .prepare = snd_card_asihpi_playback_prepare,
1081 .trigger = snd_card_asihpi_trigger,
1082 .pointer = snd_card_asihpi_playback_pointer,
1083};
1084
1085/***************************** CAPTURE OPS ****************/
1086static snd_pcm_uframes_t
1087snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1088{
1089 struct snd_pcm_runtime *runtime = substream->runtime;
1090 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1091
1092 VPRINTK2("capture pointer %d=%d\n",
1093 substream->number, dpcm->pcm_buf_pos);
1094 /* NOTE Unlike playback can't use actual dwSamplesPlayed
1095 for the capture position, because those samples aren't yet in
1096 the local buffer available for reading.
1097 */
1098 return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
1099}
1100
1101static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1102 unsigned int cmd, void *arg)
1103{
1104 return snd_pcm_lib_ioctl(substream, cmd, arg);
1105}
1106
1107static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1108{
1109 struct snd_pcm_runtime *runtime = substream->runtime;
1110 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1111
1112 hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream));
1113 dpcm->pcm_irq_pos = 0;
1114 dpcm->pcm_buf_pos = 0;
1115
1116 snd_printd("capture prepare %d\n", substream->number);
1117 return 0;
1118}
1119
1120
1121
1122static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1123 u32 h_stream,
1124 struct snd_pcm_hardware *pcmhw)
1125{
1126 struct hpi_format hpi_format;
1127 u16 format;
1128 u16 err;
1129 u32 h_control;
1130 u32 sample_rate = 48000;
1131
1132 /* on cards without SRC, must query at valid rate,
1133 maybe set by external sync */
1134 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
1135 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1136 HPI_CONTROL_SAMPLECLOCK, &h_control);
1137
1138 if (!err)
1139 err = hpi_sample_clock_get_sample_rate(ss, h_control,
1140 &sample_rate);
1141
1142 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1143 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1144
1145 err = hpi_format_create(&hpi_format, 2, format,
1146 sample_rate, 128000, 0);
1147 if (!err)
1148 err = hpi_instream_query_format(ss, h_stream,
1149 &hpi_format);
1150 if (!err)
1151 pcmhw->formats |=
1152 (1ULL << hpi_to_alsa_formats[format]);
1153 }
1154}
1155
1156
1157static struct snd_pcm_hardware snd_card_asihpi_capture = {
1158 .channels_min = 1,
1159 .channels_max = 2,
1160 .buffer_bytes_max = BUFFER_BYTES_MAX,
1161 .period_bytes_min = PERIOD_BYTES_MIN,
1162 .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1163 .periods_min = PERIODS_MIN,
1164 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1165 .fifo_size = 0,
1166};
1167
1168static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1169{
1170 struct snd_pcm_runtime *runtime = substream->runtime;
1171 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1172 struct snd_card_asihpi_pcm *dpcm;
1173 int err;
1174
1175 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1176 if (dpcm == NULL)
1177 return -ENOMEM;
1178
1179 snd_printd("hpi_instream_open adapter %d stream %d\n",
1180 card->adapter_index, substream->number);
1181
1182 err = hpi_handle_error(
1183 hpi_instream_open(ss, card->adapter_index,
1184 substream->number, &dpcm->h_stream));
1185 if (err)
1186 kfree(dpcm);
1187 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1188 return -EBUSY;
1189 if (err)
1190 return -EIO;
1191
1192
1193 init_timer(&dpcm->timer);
1194 dpcm->timer.data = (unsigned long) dpcm;
1195 dpcm->timer.function = snd_card_asihpi_timer_function;
1196 dpcm->substream = substream;
1197 runtime->private_data = dpcm;
1198 runtime->private_free = snd_card_asihpi_runtime_free;
1199
1200 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1201 snd_card_asihpi_capture_format(card, dpcm->h_stream,
1202 &snd_card_asihpi_capture);
1203 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1204 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED;
1205
1206 if (card->support_mmap)
1207 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1208 SNDRV_PCM_INFO_MMAP_VALID;
1209
1210 runtime->hw = snd_card_asihpi_capture;
1211
1212 if (card->support_mmap)
1213 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1214 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1215 if (err < 0)
1216 return err;
1217
1218 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1219 card->update_interval_frames);
1220 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1221 card->update_interval_frames * 2, UINT_MAX);
1222
1223 snd_pcm_set_sync(substream);
1224
1225 return 0;
1226}
1227
1228static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1229{
1230 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1231
1232 hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream));
1233 return 0;
1234}
1235
1236static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1237 int channel, snd_pcm_uframes_t pos,
1238 void __user *dst, snd_pcm_uframes_t count)
1239{
1240 struct snd_pcm_runtime *runtime = substream->runtime;
1241 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1242 u32 data_size;
1243
1244 data_size = frames_to_bytes(runtime, count);
1245
1246 VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size);
1247 hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream,
1248 runtime->dma_area, data_size));
1249
1250 /* Used by capture_pointer */
1251 dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1252
1253 if (copy_to_user(dst, runtime->dma_area, data_size))
1254 return -EFAULT;
1255
1256 return 0;
1257}
1258
1259static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1260 .open = snd_card_asihpi_capture_open,
1261 .close = snd_card_asihpi_capture_close,
1262 .ioctl = snd_card_asihpi_capture_ioctl,
1263 .hw_params = snd_card_asihpi_pcm_hw_params,
1264 .hw_free = snd_card_asihpi_hw_free,
1265 .prepare = snd_card_asihpi_capture_prepare,
1266 .trigger = snd_card_asihpi_trigger,
1267 .pointer = snd_card_asihpi_capture_pointer,
1268};
1269
1270static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1271 .open = snd_card_asihpi_capture_open,
1272 .close = snd_card_asihpi_capture_close,
1273 .ioctl = snd_card_asihpi_capture_ioctl,
1274 .hw_params = snd_card_asihpi_pcm_hw_params,
1275 .hw_free = snd_card_asihpi_hw_free,
1276 .prepare = snd_card_asihpi_capture_prepare,
1277 .trigger = snd_card_asihpi_trigger,
1278 .pointer = snd_card_asihpi_capture_pointer,
1279 .copy = snd_card_asihpi_capture_copy
1280};
1281
1282static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1283 int device, int substreams)
1284{
1285 struct snd_pcm *pcm;
1286 int err;
1287
1288 err = snd_pcm_new(asihpi->card, "asihpi PCM", device,
1289 asihpi->num_outstreams, asihpi->num_instreams,
1290 &pcm);
1291 if (err < 0)
1292 return err;
1293 /* pointer to ops struct is stored, dont change ops afterwards! */
1294 if (asihpi->support_mmap) {
1295 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1296 &snd_card_asihpi_playback_mmap_ops);
1297 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1298 &snd_card_asihpi_capture_mmap_ops);
1299 } else {
1300 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1301 &snd_card_asihpi_playback_ops);
1302 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1303 &snd_card_asihpi_capture_ops);
1304 }
1305
1306 pcm->private_data = asihpi;
1307 pcm->info_flags = 0;
1308 strcpy(pcm->name, "asihpi PCM");
1309
1310 /*? do we want to emulate MMAP for non-BBM cards?
1311 Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
1312 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1313 snd_dma_pci_data(asihpi->pci),
1314 64*1024, BUFFER_BYTES_MAX);
1315
1316 return 0;
1317}
1318
1319/***************************** MIXER CONTROLS ****************/
1320struct hpi_control {
1321 u32 h_control;
1322 u16 control_type;
1323 u16 src_node_type;
1324 u16 src_node_index;
1325 u16 dst_node_type;
1326 u16 dst_node_index;
1327 u16 band;
1328 char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1329};
1330
1331static char *asihpi_tuner_band_names[] =
1332{
1333 "invalid",
1334 "AM",
1335 "FM mono",
1336 "TV NTSC-M",
1337 "FM stereo",
1338 "AUX",
1339 "TV PAL BG",
1340 "TV PAL I",
1341 "TV PAL DK",
1342 "TV SECAM",
1343};
1344
1345compile_time_assert(
1346 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1347 (HPI_TUNER_BAND_LAST+1)),
1348 assert_tuner_band_names_size);
1349
1350#if ASI_STYLE_NAMES
1351static char *asihpi_src_names[] =
1352{
1353 "no source",
1354 "outstream",
1355 "line_in",
1356 "aes_in",
1357 "tuner",
1358 "RF",
1359 "clock",
1360 "bitstr",
1361 "mic",
1362 "cobranet",
1363 "analog_in",
1364 "adapter",
1365};
1366#else
1367static char *asihpi_src_names[] =
1368{
1369 "no source",
1370 "PCM playback",
1371 "line in",
1372 "digital in",
1373 "tuner",
1374 "RF",
1375 "clock",
1376 "bitstream",
1377 "mic",
1378 "cobranet in",
1379 "analog in",
1380 "adapter",
1381};
1382#endif
1383
1384compile_time_assert(
1385 (ARRAY_SIZE(asihpi_src_names) ==
1386 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_BASE+1)),
1387 assert_src_names_size);
1388
1389#if ASI_STYLE_NAMES
1390static char *asihpi_dst_names[] =
1391{
1392 "no destination",
1393 "instream",
1394 "line_out",
1395 "aes_out",
1396 "RF",
1397 "speaker" ,
1398 "cobranet",
1399 "analog_out",
1400};
1401#else
1402static char *asihpi_dst_names[] =
1403{
1404 "no destination",
1405 "PCM capture",
1406 "line out",
1407 "digital out",
1408 "RF",
1409 "speaker",
1410 "cobranet out",
1411 "analog out"
1412};
1413#endif
1414
1415compile_time_assert(
1416 (ARRAY_SIZE(asihpi_dst_names) ==
1417 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_BASE+1)),
1418 assert_dst_names_size);
1419
1420static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1421 struct snd_card_asihpi *asihpi)
1422{
1423 int err;
1424
1425 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1426 if (err < 0)
1427 return err;
1428 else if (mixer_dump)
1429 snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1430
1431 return 0;
1432}
1433
1434/* Convert HPI control name and location into ALSA control name */
1435static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1436 struct hpi_control *hpi_ctl,
1437 char *name)
1438{
1439 memset(snd_control, 0, sizeof(*snd_control));
1440 snd_control->name = hpi_ctl->name;
1441 snd_control->private_value = hpi_ctl->h_control;
1442 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1443 snd_control->index = 0;
1444
1445 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1446 sprintf(hpi_ctl->name, "%s%d to %s%d %s",
1447 asihpi_src_names[hpi_ctl->src_node_type],
1448 hpi_ctl->src_node_index,
1449 asihpi_dst_names[hpi_ctl->dst_node_type],
1450 hpi_ctl->dst_node_index,
1451 name);
1452 else if (hpi_ctl->dst_node_type) {
1453 sprintf(hpi_ctl->name, "%s%d %s",
1454 asihpi_dst_names[hpi_ctl->dst_node_type],
1455 hpi_ctl->dst_node_index,
1456 name);
1457 } else {
1458 sprintf(hpi_ctl->name, "%s%d %s",
1459 asihpi_src_names[hpi_ctl->src_node_type],
1460 hpi_ctl->src_node_index,
1461 name);
1462 }
1463}
1464
1465/*------------------------------------------------------------
1466 Volume controls
1467 ------------------------------------------------------------*/
1468#define VOL_STEP_mB 1
1469static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1470 struct snd_ctl_elem_info *uinfo)
1471{
1472 u32 h_control = kcontrol->private_value;
1473 u16 err;
1474 /* native gains are in millibels */
1475 short min_gain_mB;
1476 short max_gain_mB;
1477 short step_gain_mB;
1478
1479 err = hpi_volume_query_range(ss, h_control,
1480 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1481 if (err) {
1482 max_gain_mB = 0;
1483 min_gain_mB = -10000;
1484 step_gain_mB = VOL_STEP_mB;
1485 }
1486
1487 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1488 uinfo->count = 2;
1489 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1490 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1491 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1492 return 0;
1493}
1494
1495static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1496 struct snd_ctl_elem_value *ucontrol)
1497{
1498 u32 h_control = kcontrol->private_value;
1499 short an_gain_mB[HPI_MAX_CHANNELS];
1500
1501 hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB));
1502 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1503 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1504
1505 return 0;
1506}
1507
1508static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1509 struct snd_ctl_elem_value *ucontrol)
1510{
1511 int change;
1512 u32 h_control = kcontrol->private_value;
1513 short an_gain_mB[HPI_MAX_CHANNELS];
1514
1515 an_gain_mB[0] =
1516 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1517 an_gain_mB[1] =
1518 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1519 /* change = asihpi->mixer_volume[addr][0] != left ||
1520 asihpi->mixer_volume[addr][1] != right;
1521 */
1522 change = 1;
1523 hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB));
1524 return change;
1525}
1526
1527static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1528
1529static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1530 struct hpi_control *hpi_ctl)
1531{
1532 struct snd_card *card = asihpi->card;
1533 struct snd_kcontrol_new snd_control;
1534
1535 asihpi_ctl_init(&snd_control, hpi_ctl, "volume");
1536 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1537 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1538 snd_control.info = snd_asihpi_volume_info;
1539 snd_control.get = snd_asihpi_volume_get;
1540 snd_control.put = snd_asihpi_volume_put;
1541 snd_control.tlv.p = db_scale_100;
1542
1543 return ctl_add(card, &snd_control, asihpi);
1544}
1545
1546/*------------------------------------------------------------
1547 Level controls
1548 ------------------------------------------------------------*/
1549static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1550 struct snd_ctl_elem_info *uinfo)
1551{
1552 u32 h_control = kcontrol->private_value;
1553 u16 err;
1554 short min_gain_mB;
1555 short max_gain_mB;
1556 short step_gain_mB;
1557
1558 err =
1559 hpi_level_query_range(ss, h_control, &min_gain_mB,
1560 &max_gain_mB, &step_gain_mB);
1561 if (err) {
1562 max_gain_mB = 2400;
1563 min_gain_mB = -1000;
1564 step_gain_mB = 100;
1565 }
1566
1567 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1568 uinfo->count = 2;
1569 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1570 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1571 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1572 return 0;
1573}
1574
1575static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1576 struct snd_ctl_elem_value *ucontrol)
1577{
1578 u32 h_control = kcontrol->private_value;
1579 short an_gain_mB[HPI_MAX_CHANNELS];
1580
1581 hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB));
1582 ucontrol->value.integer.value[0] =
1583 an_gain_mB[0] / HPI_UNITS_PER_dB;
1584 ucontrol->value.integer.value[1] =
1585 an_gain_mB[1] / HPI_UNITS_PER_dB;
1586
1587 return 0;
1588}
1589
1590static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1591 struct snd_ctl_elem_value *ucontrol)
1592{
1593 int change;
1594 u32 h_control = kcontrol->private_value;
1595 short an_gain_mB[HPI_MAX_CHANNELS];
1596
1597 an_gain_mB[0] =
1598 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1599 an_gain_mB[1] =
1600 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1601 /* change = asihpi->mixer_level[addr][0] != left ||
1602 asihpi->mixer_level[addr][1] != right;
1603 */
1604 change = 1;
1605 hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB));
1606 return change;
1607}
1608
1609static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1610
1611static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1612 struct hpi_control *hpi_ctl)
1613{
1614 struct snd_card *card = asihpi->card;
1615 struct snd_kcontrol_new snd_control;
1616
1617 /* can't use 'volume' cos some nodes have volume as well */
1618 asihpi_ctl_init(&snd_control, hpi_ctl, "level");
1619 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1620 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1621 snd_control.info = snd_asihpi_level_info;
1622 snd_control.get = snd_asihpi_level_get;
1623 snd_control.put = snd_asihpi_level_put;
1624 snd_control.tlv.p = db_scale_level;
1625
1626 return ctl_add(card, &snd_control, asihpi);
1627}
1628
1629/*------------------------------------------------------------
1630 AESEBU controls
1631 ------------------------------------------------------------*/
1632
1633/* AESEBU format */
1634static char *asihpi_aesebu_format_names[] =
1635{
1636 "N/A",
1637 "S/PDIF",
1638 "AES/EBU",
1639};
1640
1641static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_info *uinfo)
1643{
1644 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1645 uinfo->count = 1;
1646 uinfo->value.enumerated.items = 3;
1647
1648 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1649 uinfo->value.enumerated.item =
1650 uinfo->value.enumerated.items - 1;
1651
1652 strcpy(uinfo->value.enumerated.name,
1653 asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1654
1655 return 0;
1656}
1657
1658static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol,
1660 u16 (*func)(const struct hpi_hsubsys *, u32, u16 *))
1661{
1662 u32 h_control = kcontrol->private_value;
1663 u16 source, err;
1664
1665 err = func(ss, h_control, &source);
1666
1667 /* default to N/A */
1668 ucontrol->value.enumerated.item[0] = 0;
1669 /* return success but set the control to N/A */
1670 if (err)
1671 return 0;
1672 if (source == HPI_AESEBU_FORMAT_SPDIF)
1673 ucontrol->value.enumerated.item[0] = 1;
1674 if (source == HPI_AESEBU_FORMAT_AESEBU)
1675 ucontrol->value.enumerated.item[0] = 2;
1676
1677 return 0;
1678}
1679
1680static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1681 struct snd_ctl_elem_value *ucontrol,
1682 u16 (*func)(const struct hpi_hsubsys *, u32, u16))
1683{
1684 u32 h_control = kcontrol->private_value;
1685
1686 /* default to S/PDIF */
1687 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1688
1689 if (ucontrol->value.enumerated.item[0] == 1)
1690 source = HPI_AESEBU_FORMAT_SPDIF;
1691 if (ucontrol->value.enumerated.item[0] == 2)
1692 source = HPI_AESEBU_FORMAT_AESEBU;
1693
1694 if (func(ss, h_control, source) != 0)
1695 return -EINVAL;
1696
1697 return 1;
1698}
1699
1700static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1701 struct snd_ctl_elem_value *ucontrol) {
1702 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1703 HPI_AESEBU__receiver_get_format);
1704}
1705
1706static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1707 struct snd_ctl_elem_value *ucontrol) {
1708 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1709 HPI_AESEBU__receiver_set_format);
1710}
1711
1712static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1713 struct snd_ctl_elem_info *uinfo)
1714{
1715 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1716 uinfo->count = 1;
1717
1718 uinfo->value.integer.min = 0;
1719 uinfo->value.integer.max = 0X1F;
1720 uinfo->value.integer.step = 1;
1721
1722 return 0;
1723}
1724
1725static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1726 struct snd_ctl_elem_value *ucontrol) {
1727
1728 u32 h_control = kcontrol->private_value;
1729 u16 status;
1730
1731 hpi_handle_error(HPI_AESEBU__receiver_get_error_status(
1732 ss, h_control, &status));
1733 ucontrol->value.integer.value[0] = status;
1734 return 0;
1735}
1736
1737static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1738 struct hpi_control *hpi_ctl)
1739{
1740 struct snd_card *card = asihpi->card;
1741 struct snd_kcontrol_new snd_control;
1742
1743 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1744 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1745 snd_control.info = snd_asihpi_aesebu_format_info;
1746 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1747 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1748
1749
1750 if (ctl_add(card, &snd_control, asihpi) < 0)
1751 return -EINVAL;
1752
1753 asihpi_ctl_init(&snd_control, hpi_ctl, "status");
1754 snd_control.access =
1755 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1756 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1757 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1758
1759 return ctl_add(card, &snd_control, asihpi);
1760}
1761
1762static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1763 struct snd_ctl_elem_value *ucontrol) {
1764 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1765 HPI_AESEBU__transmitter_get_format);
1766}
1767
1768static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1769 struct snd_ctl_elem_value *ucontrol) {
1770 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1771 HPI_AESEBU__transmitter_set_format);
1772}
1773
1774
1775static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1776 struct hpi_control *hpi_ctl)
1777{
1778 struct snd_card *card = asihpi->card;
1779 struct snd_kcontrol_new snd_control;
1780
1781 asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1782 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1783 snd_control.info = snd_asihpi_aesebu_format_info;
1784 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1785 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1786
1787 return ctl_add(card, &snd_control, asihpi);
1788}
1789
1790/*------------------------------------------------------------
1791 Tuner controls
1792 ------------------------------------------------------------*/
1793
1794/* Gain */
1795
1796static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1797 struct snd_ctl_elem_info *uinfo)
1798{
1799 u32 h_control = kcontrol->private_value;
1800 u16 err;
1801 short idx;
1802 u16 gain_range[3];
1803
1804 for (idx = 0; idx < 3; idx++) {
1805 err = hpi_tuner_query_gain(ss, h_control,
1806 idx, &gain_range[idx]);
1807 if (err != 0)
1808 return err;
1809 }
1810
1811 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1812 uinfo->count = 1;
1813 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1814 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1815 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1816 return 0;
1817}
1818
1819static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1820 struct snd_ctl_elem_value *ucontrol)
1821{
1822 /*
1823 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1824 */
1825 u32 h_control = kcontrol->private_value;
1826 short gain;
1827
1828 hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain));
1829 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1830
1831 return 0;
1832}
1833
1834static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1835 struct snd_ctl_elem_value *ucontrol)
1836{
1837 /*
1838 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1839 */
1840 u32 h_control = kcontrol->private_value;
1841 short gain;
1842
1843 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1844 hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain));
1845
1846 return 1;
1847}
1848
1849/* Band */
1850
1851static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1852 u16 *band_list, u32 len) {
1853 u32 h_control = kcontrol->private_value;
1854 u16 err = 0;
1855 u32 i;
1856
1857 for (i = 0; i < len; i++) {
1858 err = hpi_tuner_query_band(ss,
1859 h_control, i, &band_list[i]);
1860 if (err != 0)
1861 break;
1862 }
1863
1864 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1865 return -EIO;
1866
1867 return i;
1868}
1869
1870static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1871 struct snd_ctl_elem_info *uinfo)
1872{
1873 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1874 int num_bands = 0;
1875
1876 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1877 HPI_TUNER_BAND_LAST);
1878
1879 if (num_bands < 0)
1880 return num_bands;
1881
1882 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1883 uinfo->count = 1;
1884 uinfo->value.enumerated.items = num_bands;
1885
1886 if (num_bands > 0) {
1887 if (uinfo->value.enumerated.item >=
1888 uinfo->value.enumerated.items)
1889 uinfo->value.enumerated.item =
1890 uinfo->value.enumerated.items - 1;
1891
1892 strcpy(uinfo->value.enumerated.name,
1893 asihpi_tuner_band_names[
1894 tuner_bands[uinfo->value.enumerated.item]]);
1895
1896 }
1897 return 0;
1898}
1899
1900static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1901 struct snd_ctl_elem_value *ucontrol)
1902{
1903 u32 h_control = kcontrol->private_value;
1904 /*
1905 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1906 */
1907 u16 band, idx;
1908 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1909 u32 num_bands = 0;
1910
1911 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1912 HPI_TUNER_BAND_LAST);
1913
1914 hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band));
1915
1916 ucontrol->value.enumerated.item[0] = -1;
1917 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1918 if (tuner_bands[idx] == band) {
1919 ucontrol->value.enumerated.item[0] = idx;
1920 break;
1921 }
1922
1923 return 0;
1924}
1925
1926static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol)
1928{
1929 /*
1930 struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1931 */
1932 u32 h_control = kcontrol->private_value;
1933 u16 band;
1934 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1935 u32 num_bands = 0;
1936
1937 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1938 HPI_TUNER_BAND_LAST);
1939
1940 band = tuner_bands[ucontrol->value.enumerated.item[0]];
1941 hpi_handle_error(hpi_tuner_set_band(ss, h_control, band));
1942
1943 return 1;
1944}
1945
1946/* Freq */
1947
1948static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1949 struct snd_ctl_elem_info *uinfo)
1950{
1951 u32 h_control = kcontrol->private_value;
1952 u16 err;
1953 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1954 u16 num_bands = 0, band_iter, idx;
1955 u32 freq_range[3], temp_freq_range[3];
1956
1957 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1958 HPI_TUNER_BAND_LAST);
1959
1960 freq_range[0] = INT_MAX;
1961 freq_range[1] = 0;
1962 freq_range[2] = INT_MAX;
1963
1964 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1965 for (idx = 0; idx < 3; idx++) {
1966 err = hpi_tuner_query_frequency(ss, h_control,
1967 idx, tuner_bands[band_iter],
1968 &temp_freq_range[idx]);
1969 if (err != 0)
1970 return err;
1971 }
1972
1973 /* skip band with bogus stepping */
1974 if (temp_freq_range[2] <= 0)
1975 continue;
1976
1977 if (temp_freq_range[0] < freq_range[0])
1978 freq_range[0] = temp_freq_range[0];
1979 if (temp_freq_range[1] > freq_range[1])
1980 freq_range[1] = temp_freq_range[1];
1981 if (temp_freq_range[2] < freq_range[2])
1982 freq_range[2] = temp_freq_range[2];
1983 }
1984
1985 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1986 uinfo->count = 1;
1987 uinfo->value.integer.min = ((int)freq_range[0]);
1988 uinfo->value.integer.max = ((int)freq_range[1]);
1989 uinfo->value.integer.step = ((int)freq_range[2]);
1990 return 0;
1991}
1992
1993static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1994 struct snd_ctl_elem_value *ucontrol)
1995{
1996 u32 h_control = kcontrol->private_value;
1997 u32 freq;
1998
1999 hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq));
2000 ucontrol->value.integer.value[0] = freq;
2001
2002 return 0;
2003}
2004
2005static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2006 struct snd_ctl_elem_value *ucontrol)
2007{
2008 u32 h_control = kcontrol->private_value;
2009 u32 freq;
2010
2011 freq = ucontrol->value.integer.value[0];
2012 hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq));
2013
2014 return 1;
2015}
2016
2017/* Tuner control group initializer */
2018static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2019 struct hpi_control *hpi_ctl)
2020{
2021 struct snd_card *card = asihpi->card;
2022 struct snd_kcontrol_new snd_control;
2023
2024 snd_control.private_value = hpi_ctl->h_control;
2025 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2026
2027 if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) {
2028 asihpi_ctl_init(&snd_control, hpi_ctl, "gain");
2029 snd_control.info = snd_asihpi_tuner_gain_info;
2030 snd_control.get = snd_asihpi_tuner_gain_get;
2031 snd_control.put = snd_asihpi_tuner_gain_put;
2032
2033 if (ctl_add(card, &snd_control, asihpi) < 0)
2034 return -EINVAL;
2035 }
2036
2037 asihpi_ctl_init(&snd_control, hpi_ctl, "band");
2038 snd_control.info = snd_asihpi_tuner_band_info;
2039 snd_control.get = snd_asihpi_tuner_band_get;
2040 snd_control.put = snd_asihpi_tuner_band_put;
2041
2042 if (ctl_add(card, &snd_control, asihpi) < 0)
2043 return -EINVAL;
2044
2045 asihpi_ctl_init(&snd_control, hpi_ctl, "freq");
2046 snd_control.info = snd_asihpi_tuner_freq_info;
2047 snd_control.get = snd_asihpi_tuner_freq_get;
2048 snd_control.put = snd_asihpi_tuner_freq_put;
2049
2050 return ctl_add(card, &snd_control, asihpi);
2051}
2052
2053/*------------------------------------------------------------
2054 Meter controls
2055 ------------------------------------------------------------*/
2056static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2057 struct snd_ctl_elem_info *uinfo)
2058{
2059 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2060 uinfo->count = HPI_MAX_CHANNELS;
2061 uinfo->value.integer.min = 0;
2062 uinfo->value.integer.max = 0x7FFFFFFF;
2063 return 0;
2064}
2065
2066/* linear values for 10dB steps */
2067static int log2lin[] = {
2068 0x7FFFFFFF, /* 0dB */
2069 679093956,
2070 214748365,
2071 67909396,
2072 21474837,
2073 6790940,
2074 2147484, /* -60dB */
2075 679094,
2076 214748, /* -80 */
2077 67909,
2078 21475, /* -100 */
2079 6791,
2080 2147,
2081 679,
2082 214,
2083 68,
2084 21,
2085 7,
2086 2
2087};
2088
2089static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2090 struct snd_ctl_elem_value *ucontrol)
2091{
2092 u32 h_control = kcontrol->private_value;
2093 short an_gain_mB[HPI_MAX_CHANNELS], i;
2094 u16 err;
2095
2096 err = hpi_meter_get_peak(ss, h_control, an_gain_mB);
2097
2098 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2099 if (err) {
2100 ucontrol->value.integer.value[i] = 0;
2101 } else if (an_gain_mB[i] >= 0) {
2102 ucontrol->value.integer.value[i] =
2103 an_gain_mB[i] << 16;
2104 } else {
2105 /* -ve is log value in millibels < -60dB,
2106 * convert to (roughly!) linear,
2107 */
2108 ucontrol->value.integer.value[i] =
2109 log2lin[an_gain_mB[i] / -1000];
2110 }
2111 }
2112 return 0;
2113}
2114
2115static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2116 struct hpi_control *hpi_ctl, int subidx)
2117{
2118 struct snd_card *card = asihpi->card;
2119 struct snd_kcontrol_new snd_control;
2120
2121 asihpi_ctl_init(&snd_control, hpi_ctl, "meter");
2122 snd_control.access =
2123 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2124 snd_control.info = snd_asihpi_meter_info;
2125 snd_control.get = snd_asihpi_meter_get;
2126
2127 snd_control.index = subidx;
2128
2129 return ctl_add(card, &snd_control, asihpi);
2130}
2131
2132/*------------------------------------------------------------
2133 Multiplexer controls
2134 ------------------------------------------------------------*/
2135static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2136{
2137 u32 h_control = snd_control->private_value;
2138 struct hpi_control hpi_ctl;
2139 int s, err;
2140 for (s = 0; s < 32; s++) {
2141 err = hpi_multiplexer_query_source(ss, h_control, s,
2142 &hpi_ctl.
2143 src_node_type,
2144 &hpi_ctl.
2145 src_node_index);
2146 if (err)
2147 break;
2148 }
2149 return s;
2150}
2151
2152static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2153 struct snd_ctl_elem_info *uinfo)
2154{
2155 int err;
2156 u16 src_node_type, src_node_index;
2157 u32 h_control = kcontrol->private_value;
2158
2159 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2160 uinfo->count = 1;
2161 uinfo->value.enumerated.items =
2162 snd_card_asihpi_mux_count_sources(kcontrol);
2163
2164 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2165 uinfo->value.enumerated.item =
2166 uinfo->value.enumerated.items - 1;
2167
2168 err =
2169 hpi_multiplexer_query_source(ss, h_control,
2170 uinfo->value.enumerated.item,
2171 &src_node_type, &src_node_index);
2172
2173 sprintf(uinfo->value.enumerated.name, "%s %d",
2174 asihpi_src_names[src_node_type - HPI_SOURCENODE_BASE],
2175 src_node_index);
2176 return 0;
2177}
2178
2179static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2180 struct snd_ctl_elem_value *ucontrol)
2181{
2182 u32 h_control = kcontrol->private_value;
2183 u16 source_type, source_index;
2184 u16 src_node_type, src_node_index;
2185 int s;
2186
2187 hpi_handle_error(hpi_multiplexer_get_source(ss, h_control,
2188 &source_type, &source_index));
2189 /* Should cache this search result! */
2190 for (s = 0; s < 256; s++) {
2191 if (hpi_multiplexer_query_source(ss, h_control, s,
2192 &src_node_type, &src_node_index))
2193 break;
2194
2195 if ((source_type == src_node_type)
2196 && (source_index == src_node_index)) {
2197 ucontrol->value.enumerated.item[0] = s;
2198 return 0;
2199 }
2200 }
2201 snd_printd(KERN_WARNING
2202 "control %x failed to match mux source %hu %hu\n",
2203 h_control, source_type, source_index);
2204 ucontrol->value.enumerated.item[0] = 0;
2205 return 0;
2206}
2207
2208static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2209 struct snd_ctl_elem_value *ucontrol)
2210{
2211 int change;
2212 u32 h_control = kcontrol->private_value;
2213 u16 source_type, source_index;
2214 u16 e;
2215
2216 change = 1;
2217
2218 e = hpi_multiplexer_query_source(ss, h_control,
2219 ucontrol->value.enumerated.item[0],
2220 &source_type, &source_index);
2221 if (!e)
2222 hpi_handle_error(
2223 hpi_multiplexer_set_source(ss, h_control,
2224 source_type, source_index));
2225 return change;
2226}
2227
2228
2229static int __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2230 struct hpi_control *hpi_ctl)
2231{
2232 struct snd_card *card = asihpi->card;
2233 struct snd_kcontrol_new snd_control;
2234
2235#if ASI_STYLE_NAMES
2236 asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2237#else
2238 asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2239#endif
2240 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2241 snd_control.info = snd_asihpi_mux_info;
2242 snd_control.get = snd_asihpi_mux_get;
2243 snd_control.put = snd_asihpi_mux_put;
2244
2245 return ctl_add(card, &snd_control, asihpi);
2246
2247}
2248
2249/*------------------------------------------------------------
2250 Channel mode controls
2251 ------------------------------------------------------------*/
2252static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2253 struct snd_ctl_elem_info *uinfo)
2254{
2255 static char *mode_names[HPI_CHANNEL_MODE_LAST] = {
2256 "normal", "swap",
2257 "from_left", "from_right",
2258 "to_left", "to_right"
2259 };
2260
2261 u32 h_control = kcontrol->private_value;
2262 u16 mode;
2263 int i;
2264
2265 /* HPI channel mode values can be from 1 to 6
2266 Some adapters only support a contiguous subset
2267 */
2268 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2269 if (hpi_channel_mode_query_mode(
2270 ss, h_control, i, &mode))
2271 break;
2272
2273 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2274 uinfo->count = 1;
2275 uinfo->value.enumerated.items = i;
2276
2277 if (uinfo->value.enumerated.item >= i)
2278 uinfo->value.enumerated.item = i - 1;
2279
2280 strcpy(uinfo->value.enumerated.name,
2281 mode_names[uinfo->value.enumerated.item]);
2282
2283 return 0;
2284}
2285
2286static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2287 struct snd_ctl_elem_value *ucontrol)
2288{
2289 u32 h_control = kcontrol->private_value;
2290 u16 mode;
2291
2292 if (hpi_channel_mode_get(ss, h_control, &mode))
2293 mode = 1;
2294
2295 ucontrol->value.enumerated.item[0] = mode - 1;
2296
2297 return 0;
2298}
2299
2300static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2301 struct snd_ctl_elem_value *ucontrol)
2302{
2303 int change;
2304 u32 h_control = kcontrol->private_value;
2305
2306 change = 1;
2307
2308 hpi_handle_error(hpi_channel_mode_set(ss, h_control,
2309 ucontrol->value.enumerated.item[0] + 1));
2310 return change;
2311}
2312
2313
2314static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2315 struct hpi_control *hpi_ctl)
2316{
2317 struct snd_card *card = asihpi->card;
2318 struct snd_kcontrol_new snd_control;
2319
2320 asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode");
2321 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2322 snd_control.info = snd_asihpi_cmode_info;
2323 snd_control.get = snd_asihpi_cmode_get;
2324 snd_control.put = snd_asihpi_cmode_put;
2325
2326 return ctl_add(card, &snd_control, asihpi);
2327}
2328
2329/*------------------------------------------------------------
2330 Sampleclock source controls
2331 ------------------------------------------------------------*/
2332
2333static char *sampleclock_sources[MAX_CLOCKSOURCES] =
2334 { "N/A", "local PLL", "AES/EBU sync", "word external", "word header",
2335 "SMPTE", "AES/EBU in1", "auto", "network", "invalid",
2336 "prev module",
2337 "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5",
2338 "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"};
2339
2340
2341
2342static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2343 struct snd_ctl_elem_info *uinfo)
2344{
2345 struct snd_card_asihpi *asihpi =
2346 (struct snd_card_asihpi *)(kcontrol->private_data);
2347 struct clk_cache *clkcache = &asihpi->cc;
2348 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2349 uinfo->count = 1;
2350 uinfo->value.enumerated.items = clkcache->count;
2351
2352 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2353 uinfo->value.enumerated.item =
2354 uinfo->value.enumerated.items - 1;
2355
2356 strcpy(uinfo->value.enumerated.name,
2357 clkcache->s[uinfo->value.enumerated.item].name);
2358 return 0;
2359}
2360
2361static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2362 struct snd_ctl_elem_value *ucontrol)
2363{
2364 struct snd_card_asihpi *asihpi =
2365 (struct snd_card_asihpi *)(kcontrol->private_data);
2366 struct clk_cache *clkcache = &asihpi->cc;
2367 u32 h_control = kcontrol->private_value;
2368 u16 source, srcindex = 0;
2369 int i;
2370
2371 ucontrol->value.enumerated.item[0] = 0;
2372 if (hpi_sample_clock_get_source(ss, h_control, &source))
2373 source = 0;
2374
2375 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2376 if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex))
2377 srcindex = 0;
2378
2379 for (i = 0; i < clkcache->count; i++)
2380 if ((clkcache->s[i].source == source) &&
2381 (clkcache->s[i].index == srcindex))
2382 break;
2383
2384 ucontrol->value.enumerated.item[0] = i;
2385
2386 return 0;
2387}
2388
2389static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2390 struct snd_ctl_elem_value *ucontrol)
2391{
2392 struct snd_card_asihpi *asihpi =
2393 (struct snd_card_asihpi *)(kcontrol->private_data);
2394 struct clk_cache *clkcache = &asihpi->cc;
2395 int change, item;
2396 u32 h_control = kcontrol->private_value;
2397
2398 change = 1;
2399 item = ucontrol->value.enumerated.item[0];
2400 if (item >= clkcache->count)
2401 item = clkcache->count-1;
2402
2403 hpi_handle_error(hpi_sample_clock_set_source(ss,
2404 h_control, clkcache->s[item].source));
2405
2406 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2407 hpi_handle_error(hpi_sample_clock_set_source_index(ss,
2408 h_control, clkcache->s[item].index));
2409 return change;
2410}
2411
2412/*------------------------------------------------------------
2413 Clkrate controls
2414 ------------------------------------------------------------*/
2415/* Need to change this to enumerated control with list of rates */
2416static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2417 struct snd_ctl_elem_info *uinfo)
2418{
2419 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2420 uinfo->count = 1;
2421 uinfo->value.integer.min = 8000;
2422 uinfo->value.integer.max = 192000;
2423 uinfo->value.integer.step = 100;
2424
2425 return 0;
2426}
2427
2428static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2429 struct snd_ctl_elem_value *ucontrol)
2430{
2431 u32 h_control = kcontrol->private_value;
2432 u32 rate;
2433 u16 e;
2434
2435 e = hpi_sample_clock_get_local_rate(ss, h_control, &rate);
2436 if (!e)
2437 ucontrol->value.integer.value[0] = rate;
2438 else
2439 ucontrol->value.integer.value[0] = 0;
2440 return 0;
2441}
2442
2443static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2444 struct snd_ctl_elem_value *ucontrol)
2445{
2446 int change;
2447 u32 h_control = kcontrol->private_value;
2448
2449 /* change = asihpi->mixer_clkrate[addr][0] != left ||
2450 asihpi->mixer_clkrate[addr][1] != right;
2451 */
2452 change = 1;
2453 hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control,
2454 ucontrol->value.integer.value[0]));
2455 return change;
2456}
2457
2458static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2459 struct snd_ctl_elem_info *uinfo)
2460{
2461 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2462 uinfo->count = 1;
2463 uinfo->value.integer.min = 8000;
2464 uinfo->value.integer.max = 192000;
2465 uinfo->value.integer.step = 100;
2466
2467 return 0;
2468}
2469
2470static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2471 struct snd_ctl_elem_value *ucontrol)
2472{
2473 u32 h_control = kcontrol->private_value;
2474 u32 rate;
2475 u16 e;
2476
2477 e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate);
2478 if (!e)
2479 ucontrol->value.integer.value[0] = rate;
2480 else
2481 ucontrol->value.integer.value[0] = 0;
2482 return 0;
2483}
2484
2485static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2486 struct hpi_control *hpi_ctl)
2487{
2488 struct snd_card *card = asihpi->card;
2489 struct snd_kcontrol_new snd_control;
2490
2491 struct clk_cache *clkcache = &asihpi->cc;
2492 u32 hSC = hpi_ctl->h_control;
2493 int has_aes_in = 0;
2494 int i, j;
2495 u16 source;
2496
2497 snd_control.private_value = hpi_ctl->h_control;
2498
2499 clkcache->has_local = 0;
2500
2501 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2502 if (hpi_sample_clock_query_source(ss, hSC,
2503 i, &source))
2504 break;
2505 clkcache->s[i].source = source;
2506 clkcache->s[i].index = 0;
2507 clkcache->s[i].name = sampleclock_sources[source];
2508 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2509 has_aes_in = 1;
2510 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2511 clkcache->has_local = 1;
2512 }
2513 if (has_aes_in)
2514 /* already will have picked up index 0 above */
2515 for (j = 1; j < 8; j++) {
2516 if (hpi_sample_clock_query_source_index(ss, hSC,
2517 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2518 &source))
2519 break;
2520 clkcache->s[i].source =
2521 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2522 clkcache->s[i].index = j;
2523 clkcache->s[i].name = sampleclock_sources[
2524 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2525 i++;
2526 }
2527 clkcache->count = i;
2528
2529 asihpi_ctl_init(&snd_control, hpi_ctl, "source");
2530 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2531 snd_control.info = snd_asihpi_clksrc_info;
2532 snd_control.get = snd_asihpi_clksrc_get;
2533 snd_control.put = snd_asihpi_clksrc_put;
2534 if (ctl_add(card, &snd_control, asihpi) < 0)
2535 return -EINVAL;
2536
2537
2538 if (clkcache->has_local) {
2539 asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate");
2540 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2541 snd_control.info = snd_asihpi_clklocal_info;
2542 snd_control.get = snd_asihpi_clklocal_get;
2543 snd_control.put = snd_asihpi_clklocal_put;
2544
2545
2546 if (ctl_add(card, &snd_control, asihpi) < 0)
2547 return -EINVAL;
2548 }
2549
2550 asihpi_ctl_init(&snd_control, hpi_ctl, "rate");
2551 snd_control.access =
2552 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2553 snd_control.info = snd_asihpi_clkrate_info;
2554 snd_control.get = snd_asihpi_clkrate_get;
2555
2556 return ctl_add(card, &snd_control, asihpi);
2557}
2558/*------------------------------------------------------------
2559 Mixer
2560 ------------------------------------------------------------*/
2561
2562static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2563{
2564 struct snd_card *card = asihpi->card;
2565 unsigned int idx = 0;
2566 unsigned int subindex = 0;
2567 int err;
2568 struct hpi_control hpi_ctl, prev_ctl;
2569
2570 if (snd_BUG_ON(!asihpi))
2571 return -EINVAL;
2572 strcpy(card->mixername, "asihpi mixer");
2573
2574 err =
2575 hpi_mixer_open(ss, asihpi->adapter_index,
2576 &asihpi->h_mixer);
2577 hpi_handle_error(err);
2578 if (err)
2579 return -err;
2580
2581 for (idx = 0; idx < 2000; idx++) {
2582 err = hpi_mixer_get_control_by_index(
2583 ss, asihpi->h_mixer,
2584 idx,
2585 &hpi_ctl.src_node_type,
2586 &hpi_ctl.src_node_index,
2587 &hpi_ctl.dst_node_type,
2588 &hpi_ctl.dst_node_index,
2589 &hpi_ctl.control_type,
2590 &hpi_ctl.h_control);
2591 if (err) {
2592 if (err == HPI_ERROR_CONTROL_DISABLED) {
2593 if (mixer_dump)
2594 snd_printk(KERN_INFO
2595 "disabled HPI control(%d)\n",
2596 idx);
2597 continue;
2598 } else
2599 break;
2600
2601 }
2602
2603 hpi_ctl.src_node_type -= HPI_SOURCENODE_BASE;
2604 hpi_ctl.dst_node_type -= HPI_DESTNODE_BASE;
2605
2606 /* ASI50xx in SSX mode has multiple meters on the same node.
2607 Use subindex to create distinct ALSA controls
2608 for any duplicated controls.
2609 */
2610 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2611 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2612 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2613 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2614 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2615 subindex++;
2616 else
2617 subindex = 0;
2618
2619 prev_ctl = hpi_ctl;
2620
2621 switch (hpi_ctl.control_type) {
2622 case HPI_CONTROL_VOLUME:
2623 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2624 break;
2625 case HPI_CONTROL_LEVEL:
2626 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2627 break;
2628 case HPI_CONTROL_MULTIPLEXER:
2629 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2630 break;
2631 case HPI_CONTROL_CHANNEL_MODE:
2632 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2633 break;
2634 case HPI_CONTROL_METER:
2635 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2636 break;
2637 case HPI_CONTROL_SAMPLECLOCK:
2638 err = snd_asihpi_sampleclock_add(
2639 asihpi, &hpi_ctl);
2640 break;
2641 case HPI_CONTROL_CONNECTION: /* ignore these */
2642 continue;
2643 case HPI_CONTROL_TUNER:
2644 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2645 break;
2646 case HPI_CONTROL_AESEBU_TRANSMITTER:
2647 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2648 break;
2649 case HPI_CONTROL_AESEBU_RECEIVER:
2650 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2651 break;
2652 case HPI_CONTROL_VOX:
2653 case HPI_CONTROL_BITSTREAM:
2654 case HPI_CONTROL_MICROPHONE:
2655 case HPI_CONTROL_PARAMETRIC_EQ:
2656 case HPI_CONTROL_COMPANDER:
2657 default:
2658 if (mixer_dump)
2659 snd_printk(KERN_INFO
2660 "untranslated HPI control"
2661 "(%d) %d %d %d %d %d\n",
2662 idx,
2663 hpi_ctl.control_type,
2664 hpi_ctl.src_node_type,
2665 hpi_ctl.src_node_index,
2666 hpi_ctl.dst_node_type,
2667 hpi_ctl.dst_node_index);
2668 continue;
2669 };
2670 if (err < 0)
2671 return err;
2672 }
2673 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2674 hpi_handle_error(err);
2675
2676 snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2677
2678 return 0;
2679}
2680
2681/*------------------------------------------------------------
2682 /proc interface
2683 ------------------------------------------------------------*/
2684
2685static void
2686snd_asihpi_proc_read(struct snd_info_entry *entry,
2687 struct snd_info_buffer *buffer)
2688{
2689 struct snd_card_asihpi *asihpi = entry->private_data;
2690 u16 version;
2691 u32 h_control;
2692 u32 rate = 0;
2693 u16 source = 0;
2694 int err;
2695
2696 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2697 snd_iprintf(buffer,
2698 "adapter ID=%4X\n_index=%d\n"
2699 "num_outstreams=%d\n_num_instreams=%d\n",
2700 asihpi->type, asihpi->adapter_index,
2701 asihpi->num_outstreams, asihpi->num_instreams);
2702
2703 version = asihpi->version;
2704 snd_iprintf(buffer,
2705 "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
2706 asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
2707 version & 0x7,
2708 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2709
2710 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2711 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2712 HPI_CONTROL_SAMPLECLOCK, &h_control);
2713
2714 if (!err) {
2715 err = hpi_sample_clock_get_sample_rate(ss,
2716 h_control, &rate);
2717 err += hpi_sample_clock_get_source(ss, h_control, &source);
2718
2719 if (!err)
2720 snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
2721 rate, sampleclock_sources[source]);
2722 }
2723
2724}
2725
2726
2727static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2728{
2729 struct snd_info_entry *entry;
2730
2731 if (!snd_card_proc_new(asihpi->card, "info", &entry))
2732 snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2733}
2734
2735/*------------------------------------------------------------
2736 HWDEP
2737 ------------------------------------------------------------*/
2738
2739static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2740{
2741 if (enable_hpi_hwdep)
2742 return 0;
2743 else
2744 return -ENODEV;
2745
2746}
2747
2748static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2749{
2750 if (enable_hpi_hwdep)
2751 return asihpi_hpi_release(file);
2752 else
2753 return -ENODEV;
2754}
2755
2756static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2757 unsigned int cmd, unsigned long arg)
2758{
2759 if (enable_hpi_hwdep)
2760 return asihpi_hpi_ioctl(file, cmd, arg);
2761 else
2762 return -ENODEV;
2763}
2764
2765
2766/* results in /dev/snd/hwC#D0 file for each card with index #
2767 also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2768*/
2769static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2770 int device, struct snd_hwdep **rhwdep)
2771{
2772 struct snd_hwdep *hw;
2773 int err;
2774
2775 if (rhwdep)
2776 *rhwdep = NULL;
2777 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2778 if (err < 0)
2779 return err;
2780 strcpy(hw->name, "asihpi (HPI)");
2781 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2782 hw->ops.open = snd_asihpi_hpi_open;
2783 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2784 hw->ops.release = snd_asihpi_hpi_release;
2785 hw->private_data = asihpi;
2786 if (rhwdep)
2787 *rhwdep = hw;
2788 return 0;
2789}
2790
2791/*------------------------------------------------------------
2792 CARD
2793 ------------------------------------------------------------*/
2794static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2795 const struct pci_device_id *pci_id)
2796{
2797 int err;
2798
2799 u16 version;
2800 int pcm_substreams;
2801
2802 struct hpi_adapter *hpi_card;
2803 struct snd_card *card;
2804 struct snd_card_asihpi *asihpi;
2805
2806 u32 h_control;
2807 u32 h_stream;
2808
2809 static int dev;
2810 if (dev >= SNDRV_CARDS)
2811 return -ENODEV;
2812
2813 /* Should this be enable[hpi_card->index] ? */
2814 if (!enable[dev]) {
2815 dev++;
2816 return -ENOENT;
2817 }
2818
2819 err = asihpi_adapter_probe(pci_dev, pci_id);
2820 if (err < 0)
2821 return err;
2822
2823 hpi_card = pci_get_drvdata(pci_dev);
2824 /* first try to give the card the same index as its hardware index */
2825 err = snd_card_create(hpi_card->index,
2826 id[hpi_card->index], THIS_MODULE,
2827 sizeof(struct snd_card_asihpi),
2828 &card);
2829 if (err < 0) {
2830 /* if that fails, try the default index==next available */
2831 err =
2832 snd_card_create(index[dev], id[dev],
2833 THIS_MODULE,
2834 sizeof(struct snd_card_asihpi),
2835 &card);
2836 if (err < 0)
2837 return err;
2838 snd_printk(KERN_WARNING
2839 "**** WARNING **** adapter index %d->ALSA index %d\n",
2840 hpi_card->index, card->number);
2841 }
2842
2843 asihpi = (struct snd_card_asihpi *) card->private_data;
2844 asihpi->card = card;
2845 asihpi->pci = hpi_card->pci;
2846 asihpi->adapter_index = hpi_card->index;
2847 hpi_handle_error(hpi_adapter_get_info(ss,
2848 asihpi->adapter_index,
2849 &asihpi->num_outstreams,
2850 &asihpi->num_instreams,
2851 &asihpi->version,
2852 &asihpi->serial_number, &asihpi->type));
2853
2854 version = asihpi->version;
2855 snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2856 "num_instreams=%d S/N=%d\n"
2857 "hw version %c%d DSP code version %03d\n",
2858 asihpi->type, asihpi->adapter_index,
2859 asihpi->num_outstreams,
2860 asihpi->num_instreams, asihpi->serial_number,
2861 ((version >> 3) & 0xf) + 'A',
2862 version & 0x7,
2863 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2864
2865 pcm_substreams = asihpi->num_outstreams;
2866 if (pcm_substreams < asihpi->num_instreams)
2867 pcm_substreams = asihpi->num_instreams;
2868
2869 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2870 HPI_ADAPTER_PROPERTY_CAPS1,
2871 NULL, &asihpi->support_grouping);
2872 if (err)
2873 asihpi->support_grouping = 0;
2874
2875 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2876 HPI_ADAPTER_PROPERTY_CAPS2,
2877 &asihpi->support_mrx, NULL);
2878 if (err)
2879 asihpi->support_mrx = 0;
2880
2881 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2882 HPI_ADAPTER_PROPERTY_INTERVAL,
2883 NULL, &asihpi->update_interval_frames);
2884 if (err)
2885 asihpi->update_interval_frames = 512;
2886
2887 hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index,
2888 0, &h_stream));
2889
2890 err = hpi_instream_host_buffer_free(ss, h_stream);
2891 asihpi->support_mmap = (!err);
2892
2893 hpi_handle_error(hpi_instream_close(ss, h_stream));
2894
2895 err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2896 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2897 &asihpi->in_max_chans, &asihpi->out_max_chans);
2898 if (err) {
2899 asihpi->in_max_chans = 2;
2900 asihpi->out_max_chans = 2;
2901 }
2902
2903 snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n",
2904 asihpi->support_mmap,
2905 asihpi->support_grouping,
2906 asihpi->support_mrx
2907 );
2908
2909
2910 err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2911 if (err < 0) {
2912 snd_printk(KERN_ERR "pcm_new failed\n");
2913 goto __nodev;
2914 }
2915 err = snd_card_asihpi_mixer_new(asihpi);
2916 if (err < 0) {
2917 snd_printk(KERN_ERR "mixer_new failed\n");
2918 goto __nodev;
2919 }
2920
2921 err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2922 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2923 HPI_CONTROL_SAMPLECLOCK, &h_control);
2924
2925 if (!err)
2926 err = hpi_sample_clock_set_local_rate(
2927 ss, h_control, adapter_fs);
2928
2929 snd_asihpi_proc_init(asihpi);
2930
2931 /* always create, can be enabled or disabled dynamically
2932 by enable_hwdep module param*/
2933 snd_asihpi_hpi_new(asihpi, 0, NULL);
2934
2935 if (asihpi->support_mmap)
2936 strcpy(card->driver, "ASIHPI-MMAP");
2937 else
2938 strcpy(card->driver, "ASIHPI");
2939
2940 sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2941 sprintf(card->longname, "%s %i",
2942 card->shortname, asihpi->adapter_index);
2943 err = snd_card_register(card);
2944 if (!err) {
2945 hpi_card->snd_card_asihpi = card;
2946 dev++;
2947 return 0;
2948 }
2949__nodev:
2950 snd_card_free(card);
2951 snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2952 return err;
2953
2954}
2955
2956static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2957{
2958 struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
2959
2960 snd_card_free(hpi_card->snd_card_asihpi);
2961 hpi_card->snd_card_asihpi = NULL;
2962 asihpi_adapter_remove(pci_dev);
2963}
2964
2965static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2966 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2967 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2968 (kernel_ulong_t)HPI_6205},
2969 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2970 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2971 (kernel_ulong_t)HPI_6000},
2972 {0,}
2973};
2974MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2975
2976static struct pci_driver driver = {
2977 .name = "asihpi",
2978 .id_table = asihpi_pci_tbl,
2979 .probe = snd_asihpi_probe,
2980 .remove = __devexit_p(snd_asihpi_remove),
2981#ifdef CONFIG_PM
2982/* .suspend = snd_asihpi_suspend,
2983 .resume = snd_asihpi_resume, */
2984#endif
2985};
2986
2987static int __init snd_asihpi_init(void)
2988{
2989 asihpi_init();
2990 return pci_register_driver(&driver);
2991}
2992
2993static void __exit snd_asihpi_exit(void)
2994{
2995
2996 pci_unregister_driver(&driver);
2997 asihpi_exit();
2998}
2999
3000module_init(snd_asihpi_init)
3001module_exit(snd_asihpi_exit)
3002
diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h
new file mode 100644
index 000000000000..99400de6c075
--- /dev/null
+++ b/sound/pci/asihpi/hpi.h
@@ -0,0 +1,2001 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19*/
20/** \file hpi.h
21
22 AudioScience Hardware Programming Interface (HPI)
23 public API definition.
24
25 The HPI is a low-level hardware abstraction layer to all
26 AudioScience digital audio adapters
27*/
28/*
29 You must define one operating system that the HPI is to be compiled under
30 HPI_OS_WIN32_USER 32bit Windows
31 HPI_OS_DSP_C6000 DSP TI C6000 (automatically set)
32 HPI_OS_WDM Windows WDM kernel driver
33 HPI_OS_LINUX Linux userspace
34 HPI_OS_LINUX_KERNEL Linux kernel (automatically set)
35
36(C) Copyright AudioScience Inc. 1998-2010
37******************************************************************************/
38#ifndef _HPI_H_
39#define _HPI_H_
40/* HPI Version
41If HPI_VER_MINOR is odd then its a development release not intended for the
42public. If HPI_VER_MINOR is even then is a release version
43i.e 3.05.02 is a development version
44*/
45#define HPI_VERSION_CONSTRUCTOR(maj, min, rel) \
46 ((maj << 16) + (min << 8) + rel)
47
48#define HPI_VER_MAJOR(v) ((int)(v >> 16))
49#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
50#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
51
52/* Use single digits for versions less that 10 to avoid octal. */
53#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 18)
54
55/* Library version as documented in hpi-api-versions.txt */
56#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
57
58#include <linux/types.h>
59#define HPI_EXCLUDE_DEPRECATED
60
61/******************************************************************************/
62/******************************************************************************/
63/******** HPI API DEFINITIONS *****/
64/******************************************************************************/
65/******************************************************************************/
66/*******************************************/
67/** Audio format types
68\ingroup stream
69*/
70enum HPI_FORMATS {
71/** Used internally on adapter. */
72 HPI_FORMAT_MIXER_NATIVE = 0,
73/** 8-bit unsigned PCM. Windows equivalent is WAVE_FORMAT_PCM. */
74 HPI_FORMAT_PCM8_UNSIGNED = 1,
75/** 16-bit signed PCM. Windows equivalent is WAVE_FORMAT_PCM. */
76 HPI_FORMAT_PCM16_SIGNED = 2,
77/** MPEG-1 Layer-1. */
78 HPI_FORMAT_MPEG_L1 = 3,
79/** MPEG-1 Layer-2.
80
81Windows equivalent is WAVE_FORMAT_MPEG.
82
83The following table shows what combinations of mode and bitrate are possible:
84
85<table border=1 cellspacing=0 cellpadding=5>
86<tr>
87<td><p><b>Bitrate (kbs)</b></p>
88<td><p><b>Mono</b></p>
89<td><p><b>Stereo,<br>Joint Stereo or<br>Dual Channel</b></p>
90
91<tr><td>32<td>X<td>_
92<tr><td>40<td>_<td>_
93<tr><td>48<td>X<td>_
94<tr><td>56<td>X<td>_
95<tr><td>64<td>X<td>X
96<tr><td>80<td>X<td>_
97<tr><td>96<td>X<td>X
98<tr><td>112<td>X<td>X
99<tr><td>128<td>X<td>X
100<tr><td>160<td>X<td>X
101<tr><td>192<td>X<td>X
102<tr><td>224<td>_<td>X
103<tr><td>256<td>-<td>X
104<tr><td>320<td>-<td>X
105<tr><td>384<td>_<td>X
106</table>
107*/
108 HPI_FORMAT_MPEG_L2 = 4,
109/** MPEG-1 Layer-3.
110Windows equivalent is WAVE_FORMAT_MPEG.
111
112The following table shows what combinations of mode and bitrate are possible:
113
114<table border=1 cellspacing=0 cellpadding=5>
115<tr>
116<td><p><b>Bitrate (kbs)</b></p>
117<td><p><b>Mono<br>Stereo @ 8,<br>11.025 and<br>12kHz*</b></p>
118<td><p><b>Mono<br>Stereo @ 16,<br>22.050 and<br>24kHz*</b></p>
119<td><p><b>Mono<br>Stereo @ 32,<br>44.1 and<br>48kHz</b></p>
120
121<tr><td>16<td>X<td>X<td>_
122<tr><td>24<td>X<td>X<td>_
123<tr><td>32<td>X<td>X<td>X
124<tr><td>40<td>X<td>X<td>X
125<tr><td>48<td>X<td>X<td>X
126<tr><td>56<td>X<td>X<td>X
127<tr><td>64<td>X<td>X<td>X
128<tr><td>80<td>_<td>X<td>X
129<tr><td>96<td>_<td>X<td>X
130<tr><td>112<td>_<td>X<td>X
131<tr><td>128<td>_<td>X<td>X
132<tr><td>144<td>_<td>X<td>_
133<tr><td>160<td>_<td>X<td>X
134<tr><td>192<td>_<td>_<td>X
135<tr><td>224<td>_<td>_<td>X
136<tr><td>256<td>-<td>_<td>X
137<tr><td>320<td>-<td>_<td>X
138</table>
139\b * Available on the ASI6000 series only
140*/
141 HPI_FORMAT_MPEG_L3 = 5,
142/** Dolby AC-2. */
143 HPI_FORMAT_DOLBY_AC2 = 6,
144/** Dolbt AC-3. */
145 HPI_FORMAT_DOLBY_AC3 = 7,
146/** 16-bit PCM big-endian. */
147 HPI_FORMAT_PCM16_BIGENDIAN = 8,
148/** TAGIT-1 algorithm - hits. */
149 HPI_FORMAT_AA_TAGIT1_HITS = 9,
150/** TAGIT-1 algorithm - inserts. */
151 HPI_FORMAT_AA_TAGIT1_INSERTS = 10,
152/** 32-bit signed PCM. Windows equivalent is WAVE_FORMAT_PCM.
153Each sample is a 32bit word. The most significant 24 bits contain a 24-bit
154sample and the least significant 8 bits are set to 0.
155*/
156 HPI_FORMAT_PCM32_SIGNED = 11,
157/** Raw bitstream - unknown format. */
158 HPI_FORMAT_RAW_BITSTREAM = 12,
159/** TAGIT-1 algorithm hits - extended. */
160 HPI_FORMAT_AA_TAGIT1_HITS_EX1 = 13,
161/** 32-bit PCM as an IEEE float. Windows equivalent is WAVE_FORMAT_IEEE_FLOAT.
162Each sample is a 32bit word in IEEE754 floating point format.
163The range is +1.0 to -1.0, which corresponds to digital fullscale.
164*/
165 HPI_FORMAT_PCM32_FLOAT = 14,
166/** 24-bit PCM signed. Windows equivalent is WAVE_FORMAT_PCM. */
167 HPI_FORMAT_PCM24_SIGNED = 15,
168/** OEM format 1 - private. */
169 HPI_FORMAT_OEM1 = 16,
170/** OEM format 2 - private. */
171 HPI_FORMAT_OEM2 = 17,
172/** Undefined format. */
173 HPI_FORMAT_UNDEFINED = 0xffff
174};
175
176/******************************************* in/out Stream states */
177/*******************************************/
178/** Stream States
179\ingroup stream
180*/
181enum HPI_STREAM_STATES {
182 /** State stopped - stream is stopped. */
183 HPI_STATE_STOPPED = 1,
184 /** State playing - stream is playing audio. */
185 HPI_STATE_PLAYING = 2,
186 /** State recording - stream is recording. */
187 HPI_STATE_RECORDING = 3,
188 /** State drained - playing stream ran out of data to play. */
189 HPI_STATE_DRAINED = 4,
190 /** State generate sine - to be implemented. */
191 HPI_STATE_SINEGEN = 5,
192 /** State wait - used for inter-card sync to mean waiting for all
193 cards to be ready. */
194 HPI_STATE_WAIT = 6
195};
196/******************************************* mixer source node types */
197/** Source node types
198\ingroup mixer
199*/
200enum HPI_SOURCENODES {
201 /** This define can be used instead of 0 to indicate
202 that there is no valid source node. A control that
203 exists on a destination node can be searched for using a source
204 node value of either 0, or HPI_SOURCENODE_NONE */
205 HPI_SOURCENODE_NONE = 100,
206 /** \deprecated Use HPI_SOURCENODE_NONE instead. */
207 HPI_SOURCENODE_BASE = 100,
208 /** Out Stream (Play) node. */
209 HPI_SOURCENODE_OSTREAM = 101,
210 /** Line in node - could be analog, AES/EBU or network. */
211 HPI_SOURCENODE_LINEIN = 102,
212 HPI_SOURCENODE_AESEBU_IN = 103, /**< AES/EBU input node. */
213 HPI_SOURCENODE_TUNER = 104, /**< tuner node. */
214 HPI_SOURCENODE_RF = 105, /**< RF input node. */
215 HPI_SOURCENODE_CLOCK_SOURCE = 106, /**< clock source node. */
216 HPI_SOURCENODE_RAW_BITSTREAM = 107, /**< raw bitstream node. */
217 HPI_SOURCENODE_MICROPHONE = 108, /**< microphone node. */
218 /** Cobranet input node -
219 Audio samples come from the Cobranet network and into the device. */
220 HPI_SOURCENODE_COBRANET = 109,
221 HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */
222 HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */
223 /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
224 HPI_SOURCENODE_LAST_INDEX = 111 /**< largest ID */
225 /* AX6 max sourcenode types = 15 */
226};
227
228/******************************************* mixer dest node types */
229/** Destination node types
230\ingroup mixer
231*/
232enum HPI_DESTNODES {
233 /** This define can be used instead of 0 to indicate
234 that there is no valid destination node. A control that
235 exists on a source node can be searched for using a destination
236 node value of either 0, or HPI_DESTNODE_NONE */
237 HPI_DESTNODE_NONE = 200,
238 /** \deprecated Use HPI_DESTNODE_NONE instead. */
239 HPI_DESTNODE_BASE = 200,
240 /** In Stream (Record) node. */
241 HPI_DESTNODE_ISTREAM = 201,
242 HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
243 HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */
244 HPI_DESTNODE_RF = 204, /**< RF output node. */
245 HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */
246 /** Cobranet output node -
247 Audio samples from the device are sent out on the Cobranet network.*/
248 HPI_DESTNODE_COBRANET = 206,
249 HPI_DESTNODE_ANALOG = 207, /**< analog output node. */
250
251 /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
252 HPI_DESTNODE_LAST_INDEX = 207 /**< largest ID */
253 /* AX6 max destnode types = 15 */
254};
255
256/*******************************************/
257/** Mixer control types
258\ingroup mixer
259*/
260enum HPI_CONTROLS {
261 HPI_CONTROL_GENERIC = 0, /**< generic control. */
262 HPI_CONTROL_CONNECTION = 1, /**< A connection between nodes. */
263 HPI_CONTROL_VOLUME = 2, /**< volume control - works in dB_fs. */
264 HPI_CONTROL_METER = 3, /**< peak meter control. */
265 HPI_CONTROL_MUTE = 4, /*mute control - not used at present. */
266 HPI_CONTROL_MULTIPLEXER = 5, /**< multiplexer control. */
267
268 HPI_CONTROL_AESEBU_TRANSMITTER = 6, /**< AES/EBU transmitter control. */
269 HPI_CONTROL_AESEBUTX = HPI_CONTROL_AESEBU_TRANSMITTER,
270
271 HPI_CONTROL_AESEBU_RECEIVER = 7, /**< AES/EBU receiver control. */
272 HPI_CONTROL_AESEBURX = HPI_CONTROL_AESEBU_RECEIVER,
273
274 HPI_CONTROL_LEVEL = 8, /**< level/trim control - works in d_bu. */
275 HPI_CONTROL_TUNER = 9, /**< tuner control. */
276/* HPI_CONTROL_ONOFFSWITCH = 10 */
277 HPI_CONTROL_VOX = 11, /**< vox control. */
278/* HPI_CONTROL_AES18_TRANSMITTER = 12 */
279/* HPI_CONTROL_AES18_RECEIVER = 13 */
280/* HPI_CONTROL_AES18_BLOCKGENERATOR = 14 */
281 HPI_CONTROL_CHANNEL_MODE = 15, /**< channel mode control. */
282
283 HPI_CONTROL_BITSTREAM = 16, /**< bitstream control. */
284 HPI_CONTROL_SAMPLECLOCK = 17, /**< sample clock control. */
285 HPI_CONTROL_MICROPHONE = 18, /**< microphone control. */
286 HPI_CONTROL_PARAMETRIC_EQ = 19, /**< parametric EQ control. */
287 HPI_CONTROL_EQUALIZER = HPI_CONTROL_PARAMETRIC_EQ,
288
289 HPI_CONTROL_COMPANDER = 20, /**< compander control. */
290 HPI_CONTROL_COBRANET = 21, /**< cobranet control. */
291 HPI_CONTROL_TONEDETECTOR = 22, /**< tone detector control. */
292 HPI_CONTROL_SILENCEDETECTOR = 23, /**< silence detector control. */
293 HPI_CONTROL_PAD = 24, /**< tuner PAD control. */
294 HPI_CONTROL_SRC = 25, /**< samplerate converter control. */
295 HPI_CONTROL_UNIVERSAL = 26, /**< universal control. */
296
297/* !!! Update this AND hpidebug.h if you add a new control type!!!*/
298 HPI_CONTROL_LAST_INDEX = 26 /**<highest control type ID */
299/* WARNING types 256 or greater impact bit packing in all AX6 DSP code */
300};
301
302/* Shorthand names that match attribute names */
303
304/******************************************* ADAPTER ATTRIBUTES ****/
305
306/** Adapter properties
307These are used in HPI_AdapterSetProperty() and HPI_AdapterGetProperty()
308\ingroup adapter
309*/
310enum HPI_ADAPTER_PROPERTIES {
311/** \internal Used in dwProperty field of HPI_AdapterSetProperty() and
312HPI_AdapterGetProperty(). This errata applies to all ASI6000 cards with both
313analog and digital outputs. The CS4224 A/D+D/A has a one sample delay between
314left and right channels on both its input (ADC) and output (DAC).
315More details are available in Cirrus Logic errata ER284B2.
316PDF available from www.cirrus.com, released by Cirrus in 2001.
317*/
318 HPI_ADAPTER_PROPERTY_ERRATA_1 = 1,
319
320/** Adapter grouping property
321Indicates whether the adapter supports the grouping API (for ASIO and SSX2)
322*/
323 HPI_ADAPTER_PROPERTY_GROUPING = 2,
324
325/** Driver SSX2 property
326Tells the kernel driver to turn on SSX2 stream mapping.
327This feature is not used by the DSP. In fact the call is completely processed
328by the driver and is not passed on to the DSP at all.
329*/
330 HPI_ADAPTER_PROPERTY_ENABLE_SSX2 = 3,
331
332/** Adapter SSX2 property
333Indicates the state of the adapter's SSX2 setting. This setting is stored in
334non-volatile memory on the adapter. A typical call sequence would be to use
335HPI_ADAPTER_PROPERTY_SSX2_SETTING to set SSX2 on the adapter and then to reload
336the driver. The driver would query HPI_ADAPTER_PROPERTY_SSX2_SETTING during startup
337and if SSX2 is set, it would then call HPI_ADAPTER_PROPERTY_ENABLE_SSX2 to enable
338SSX2 stream mapping within the kernel level of the driver.
339*/
340 HPI_ADAPTER_PROPERTY_SSX2_SETTING = 4,
341
342/** Base number for readonly properties */
343 HPI_ADAPTER_PROPERTY_READONLYBASE = 256,
344
345/** Readonly adapter latency property.
346This property returns in the input and output latency in samples.
347Property 1 is the estimated input latency
348in samples, while Property 2 is that output latency in samples.
349*/
350 HPI_ADAPTER_PROPERTY_LATENCY = 256,
351
352/** Readonly adapter granularity property.
353The granulariy is the smallest size chunk of stereo samples that is processed by
354the adapter.
355This property returns the record granularity in samples in Property 1.
356Property 2 returns the play granularity.
357*/
358 HPI_ADAPTER_PROPERTY_GRANULARITY = 257,
359
360/** Readonly adapter number of current channels property.
361Property 1 is the number of record channels per record device.
362Property 2 is the number of play channels per playback device.*/
363 HPI_ADAPTER_PROPERTY_CURCHANNELS = 258,
364
365/** Readonly adapter software version.
366The SOFTWARE_VERSION property returns the version of the software running
367on the adapter as Major.Minor.Release.
368Property 1 contains Major in bits 15..8 and Minor in bits 7..0.
369Property 2 contains Release in bits 7..0. */
370 HPI_ADAPTER_PROPERTY_SOFTWARE_VERSION = 259,
371
372/** Readonly adapter MAC address MSBs.
373The MAC_ADDRESS_MSB property returns
374the most significant 32 bits of the MAC address.
375Property 1 contains bits 47..32 of the MAC address.
376Property 2 contains bits 31..16 of the MAC address. */
377 HPI_ADAPTER_PROPERTY_MAC_ADDRESS_MSB = 260,
378
379/** Readonly adapter MAC address LSBs
380The MAC_ADDRESS_LSB property returns
381the least significant 16 bits of the MAC address.
382Property 1 contains bits 15..0 of the MAC address. */
383 HPI_ADAPTER_PROPERTY_MAC_ADDRESS_LSB = 261,
384
385/** Readonly extended adapter type number
386The EXTENDED_ADAPTER_TYPE property returns the 4 digits of an extended
387adapter type, i.e ASI8920-0022, 0022 is the extended type.
388The digits are returned as ASCII characters rather than the hex digits that
389are returned for the main type
390Property 1 returns the 1st two (left most) digits, i.e "00"
391in the example above, the upper byte being the left most digit.
392Property 2 returns the 2nd two digits, i.e "22" in the example above*/
393 HPI_ADAPTER_PROPERTY_EXTENDED_ADAPTER_TYPE = 262,
394
395/** Readonly debug log buffer information */
396 HPI_ADAPTER_PROPERTY_LOGTABLEN = 263,
397 HPI_ADAPTER_PROPERTY_LOGTABBEG = 264,
398
399/** Readonly adapter IP address
400For 192.168.1.101
401Property 1 returns the 1st two (left most) digits, i.e 192*256 + 168
402in the example above, the upper byte being the left most digit.
403Property 2 returns the 2nd two digits, i.e 1*256 + 101 in the example above, */
404 HPI_ADAPTER_PROPERTY_IP_ADDRESS = 265,
405
406/** Readonly adapter buffer processed count. Returns a buffer processed count
407that is incremented every time all buffers for all streams are updated. This
408is useful for checking completion of all stream operations across the adapter
409when using grouped streams.
410*/
411 HPI_ADAPTER_PROPERTY_BUFFER_UPDATE_COUNT = 266,
412
413/** Readonly mixer and stream intervals
414
415These intervals are measured in mixer frames.
416To convert to time, divide by the adapter samplerate.
417
418The mixer interval is the number of frames processed in one mixer iteration.
419The stream update interval is the interval at which streams check for and
420process data, and BBM host buffer counters are updated.
421
422Property 1 is the mixer interval in mixer frames.
423Property 2 is the stream update interval in mixer frames.
424*/
425 HPI_ADAPTER_PROPERTY_INTERVAL = 267,
426/** Adapter capabilities 1
427Property 1 - adapter can do multichannel (SSX1)
428Property 2 - adapter can do stream grouping (supports SSX2)
429*/
430 HPI_ADAPTER_PROPERTY_CAPS1 = 268,
431/** Adapter capabilities 2
432Property 1 - adapter can do samplerate conversion (MRX)
433Property 2 - adapter can do timestretch (TSX)
434*/
435 HPI_ADAPTER_PROPERTY_CAPS2 = 269
436};
437
438/** Adapter mode commands
439
440Used in wQueryOrSet field of HPI_AdapterSetModeEx().
441\ingroup adapter
442*/
443enum HPI_ADAPTER_MODE_CMDS {
444 HPI_ADAPTER_MODE_SET = 0,
445 HPI_ADAPTER_MODE_QUERY = 1
446};
447
448/** Adapter Modes
449 These are used by HPI_AdapterSetModeEx()
450
451\warning - more than 16 possible modes breaks
452a bitmask in the Windows WAVE DLL
453\ingroup adapter
454*/
455enum HPI_ADAPTER_MODES {
456/** 4 outstream mode.
457- ASI6114: 1 instream
458- ASI6044: 4 instreams
459- ASI6012: 1 instream
460- ASI6102: no instreams
461- ASI6022, ASI6122: 2 instreams
462- ASI5111, ASI5101: 2 instreams
463- ASI652x, ASI662x: 2 instreams
464- ASI654x, ASI664x: 4 instreams
465*/
466 HPI_ADAPTER_MODE_4OSTREAM = 1,
467
468/** 6 outstream mode.
469- ASI6012: 1 instream,
470- ASI6022, ASI6122: 2 instreams
471- ASI652x, ASI662x: 4 instreams
472*/
473 HPI_ADAPTER_MODE_6OSTREAM = 2,
474
475/** 8 outstream mode.
476- ASI6114: 8 instreams
477- ASI6118: 8 instreams
478- ASI6585: 8 instreams
479*/
480 HPI_ADAPTER_MODE_8OSTREAM = 3,
481
482/** 16 outstream mode.
483- ASI6416 16 instreams
484- ASI6518, ASI6618 16 instreams
485- ASI6118 16 mono out and in streams
486*/
487 HPI_ADAPTER_MODE_16OSTREAM = 4,
488
489/** one outstream mode.
490- ASI5111 1 outstream, 1 instream
491*/
492 HPI_ADAPTER_MODE_1OSTREAM = 5,
493
494/** ASI504X mode 1. 12 outstream, 4 instream 0 to 48kHz sample rates
495 (see ASI504X datasheet for more info).
496*/
497 HPI_ADAPTER_MODE_1 = 6,
498
499/** ASI504X mode 2. 4 outstreams, 4 instreams at 0 to 192kHz sample rates
500 (see ASI504X datasheet for more info).
501*/
502 HPI_ADAPTER_MODE_2 = 7,
503
504/** ASI504X mode 3. 4 outstreams, 4 instreams at 0 to 192kHz sample rates
505 (see ASI504X datasheet for more info).
506*/
507 HPI_ADAPTER_MODE_3 = 8,
508
509/** ASI504X multichannel mode.
510 2 outstreams -> 4 line outs = 1 to 8 channel streams),
511 4 lineins -> 1 instream (1 to 8 channel streams) at 0-48kHz.
512 For more info see the SSX Specification.
513*/
514 HPI_ADAPTER_MODE_MULTICHANNEL = 9,
515
516/** 12 outstream mode.
517- ASI6514, ASI6614: 2 instreams
518- ASI6540,ASI6544: 8 instreams
519- ASI6640,ASI6644: 8 instreams
520*/
521 HPI_ADAPTER_MODE_12OSTREAM = 10,
522
523/** 9 outstream mode.
524- ASI6044: 8 instreams
525*/
526 HPI_ADAPTER_MODE_9OSTREAM = 11,
527
528/** mono mode.
529- ASI6416: 16 outstreams/instreams
530- ASI5402: 2 outstreams/instreams
531*/
532 HPI_ADAPTER_MODE_MONO = 12,
533
534/** Low latency mode.
535- ASI6416/ASI6316: 1 16 channel outstream and instream
536*/
537 HPI_ADAPTER_MODE_LOW_LATENCY = 13
538};
539
540/* Note, adapters can have more than one capability -
541encoding as bitfield is recommended. */
542#define HPI_CAPABILITY_NONE (0)
543#define HPI_CAPABILITY_MPEG_LAYER3 (1)
544
545/* Set this equal to maximum capability index,
546Must not be greater than 32 - see axnvdef.h */
547#define HPI_CAPABILITY_MAX 1
548/* #define HPI_CAPABILITY_AAC 2 */
549
550/******************************************* STREAM ATTRIBUTES ****/
551
552/** MPEG Ancillary Data modes
553
554The mode for the ancillary data insertion or extraction to operate in.
555\ingroup stream
556*/
557enum HPI_MPEG_ANC_MODES {
558 /** the MPEG frames have energy information stored in them (5 bytes per stereo frame, 3 per mono) */
559 HPI_MPEG_ANC_HASENERGY = 0,
560 /** the entire ancillary data field is taken up by data from the Anc data buffer
561 On encode, the encoder will insert the energy bytes before filling the remainder
562 of the ancillary data space with data from the ancillary data buffer.
563 */
564 HPI_MPEG_ANC_RAW = 1
565};
566
567/** Ancillary Data Alignment
568\ingroup instream
569*/
570enum HPI_ISTREAM_MPEG_ANC_ALIGNS {
571 /** data is packed against the end of data, then padded to the end of frame */
572 HPI_MPEG_ANC_ALIGN_LEFT = 0,
573 /** data is packed against the end of the frame */
574 HPI_MPEG_ANC_ALIGN_RIGHT = 1
575};
576
577/** MPEG modes
578MPEG modes - can be used optionally for HPI_FormatCreate()
579parameter dwAttributes.
580
581Using any mode setting other than HPI_MPEG_MODE_DEFAULT
582with single channel format will return an error.
583\ingroup stream
584*/
585enum HPI_MPEG_MODES {
586/** Causes the MPEG-1 Layer II bitstream to be recorded
587in single_channel mode when the number of channels is 1 and in stereo when the
588number of channels is 2. */
589 HPI_MPEG_MODE_DEFAULT = 0,
590 /** Standard stereo without joint-stereo compression */
591 HPI_MPEG_MODE_STEREO = 1,
592 /** Joint stereo */
593 HPI_MPEG_MODE_JOINTSTEREO = 2,
594 /** Left and Right channels are completely independent */
595 HPI_MPEG_MODE_DUALCHANNEL = 3
596};
597/******************************************* MIXER ATTRIBUTES ****/
598
599/* \defgroup mixer_flags Mixer flags for HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES
600{
601*/
602#define HPI_MIXER_GET_CONTROL_MULTIPLE_CHANGED (0)
603#define HPI_MIXER_GET_CONTROL_MULTIPLE_RESET (1)
604/*}*/
605
606/** Commands used by HPI_MixerStore()
607\ingroup mixer
608*/
609enum HPI_MIXER_STORE_COMMAND {
610/** Save all mixer control settings. */
611 HPI_MIXER_STORE_SAVE = 1,
612/** Restore all controls from saved. */
613 HPI_MIXER_STORE_RESTORE = 2,
614/** Delete saved control settings. */
615 HPI_MIXER_STORE_DELETE = 3,
616/** Enable auto storage of some control settings. */
617 HPI_MIXER_STORE_ENABLE = 4,
618/** Disable auto storage of some control settings. */
619 HPI_MIXER_STORE_DISABLE = 5,
620/** Save the attributes of a single control. */
621 HPI_MIXER_STORE_SAVE_SINGLE = 6
622};
623
624/************************************* CONTROL ATTRIBUTE VALUES ****/
625/** Used by mixer plugin enable functions
626
627E.g. HPI_ParametricEQ_SetState()
628\ingroup mixer
629*/
630enum HPI_SWITCH_STATES {
631 HPI_SWITCH_OFF = 0, /**< turn the mixer plugin on. */
632 HPI_SWITCH_ON = 1 /**< turn the mixer plugin off. */
633};
634
635/* Volume control special gain values */
636/** volumes units are 100ths of a dB
637\ingroup volume
638*/
639#define HPI_UNITS_PER_dB 100
640/** turns volume control OFF or MUTE
641\ingroup volume
642*/
643#define HPI_GAIN_OFF (-100 * HPI_UNITS_PER_dB)
644
645/** value returned for no signal
646\ingroup meter
647*/
648#define HPI_METER_MINIMUM (-150 * HPI_UNITS_PER_dB)
649
650/** autofade profiles
651\ingroup volume
652*/
653enum HPI_VOLUME_AUTOFADES {
654/** log fade - dB attenuation changes linearly over time */
655 HPI_VOLUME_AUTOFADE_LOG = 2,
656/** linear fade - amplitude changes linearly */
657 HPI_VOLUME_AUTOFADE_LINEAR = 3
658};
659
660/** The physical encoding format of the AESEBU I/O.
661
662Used in HPI_AESEBU_Transmitter_SetFormat(), HPI_AESEBU_Receiver_SetFormat()
663along with related Get and Query functions
664\ingroup aestx
665*/
666enum HPI_AESEBU_FORMATS {
667/** AES/EBU physical format - AES/EBU balanced "professional" */
668 HPI_AESEBU_FORMAT_AESEBU = 1,
669/** AES/EBU physical format - S/PDIF unbalanced "consumer" */
670 HPI_AESEBU_FORMAT_SPDIF = 2
671};
672
673/** AES/EBU error status bits
674
675Returned by HPI_AESEBU_Receiver_GetErrorStatus()
676\ingroup aesrx
677*/
678enum HPI_AESEBU_ERRORS {
679/** bit0: 1 when PLL is not locked */
680 HPI_AESEBU_ERROR_NOT_LOCKED = 0x01,
681/** bit1: 1 when signal quality is poor */
682 HPI_AESEBU_ERROR_POOR_QUALITY = 0x02,
683/** bit2: 1 when there is a parity error */
684 HPI_AESEBU_ERROR_PARITY_ERROR = 0x04,
685/** bit3: 1 when there is a bi-phase coding violation */
686 HPI_AESEBU_ERROR_BIPHASE_VIOLATION = 0x08,
687/** bit4: 1 when the validity bit is high */
688 HPI_AESEBU_ERROR_VALIDITY = 0x10,
689/** bit5: 1 when the CRC error bit is high */
690 HPI_AESEBU_ERROR_CRC = 0x20
691};
692
693/** \addtogroup pad
694\{
695*/
696/** The text string containing the station/channel combination. */
697#define HPI_PAD_CHANNEL_NAME_LEN 16
698/** The text string containing the artist. */
699#define HPI_PAD_ARTIST_LEN 64
700/** The text string containing the title. */
701#define HPI_PAD_TITLE_LEN 64
702/** The text string containing the comment. */
703#define HPI_PAD_COMMENT_LEN 256
704/** The PTY when the tuner has not recieved any PTY. */
705#define HPI_PAD_PROGRAM_TYPE_INVALID 0xffff
706/** \} */
707
708/** Data types for PTY string translation.
709\ingroup rds
710*/
711enum eHPI_RDS_type {
712 HPI_RDS_DATATYPE_RDS = 0, /**< RDS bitstream.*/
713 HPI_RDS_DATATYPE_RBDS = 1 /**< RBDS bitstream.*/
714};
715
716/** Tuner bands
717
718Used for HPI_Tuner_SetBand(),HPI_Tuner_GetBand()
719\ingroup tuner
720*/
721enum HPI_TUNER_BAND {
722 HPI_TUNER_BAND_AM = 1, /**< AM band */
723 HPI_TUNER_BAND_FM = 2, /**< FM band (mono) */
724 HPI_TUNER_BAND_TV_NTSC_M = 3, /**< NTSC-M TV band*/
725 HPI_TUNER_BAND_TV = 3, /* use TV_NTSC_M */
726 HPI_TUNER_BAND_FM_STEREO = 4, /**< FM band (stereo) */
727 HPI_TUNER_BAND_AUX = 5, /**< auxiliary input */
728 HPI_TUNER_BAND_TV_PAL_BG = 6, /**< PAL-B/G TV band*/
729 HPI_TUNER_BAND_TV_PAL_I = 7, /**< PAL-I TV band*/
730 HPI_TUNER_BAND_TV_PAL_DK = 8, /**< PAL-D/K TV band*/
731 HPI_TUNER_BAND_TV_SECAM_L = 9, /**< SECAM-L TV band*/
732 HPI_TUNER_BAND_LAST = 9 /**< the index of the last tuner band. */
733};
734
735/** Tuner mode attributes
736
737Used by HPI_Tuner_SetMode(), HPI_Tuner_GetMode()
738\ingroup tuner
739
740*/
741enum HPI_TUNER_MODES {
742 HPI_TUNER_MODE_RSS = 1, /**< control RSS */
743 HPI_TUNER_MODE_RDS = 2 /**< control RBDS/RDS */
744};
745
746/** Tuner mode attribute values
747
748Used by HPI_Tuner_SetMode(), HPI_Tuner_GetMode()
749\ingroup tuner
750*/
751enum HPI_TUNER_MODE_VALUES {
752/* RSS attribute values */
753 HPI_TUNER_MODE_RSS_DISABLE = 0, /**< RSS disable */
754 HPI_TUNER_MODE_RSS_ENABLE = 1, /**< RSS enable */
755
756/* RDS mode attributes */
757 HPI_TUNER_MODE_RDS_DISABLE = 0, /**< RDS - disabled */
758 HPI_TUNER_MODE_RDS_RDS = 1, /**< RDS - RDS mode */
759 HPI_TUNER_MODE_RDS_RBDS = 2 /**< RDS - RBDS mode */
760};
761
762/** Tuner Level settings
763\ingroup tuner
764*/
765enum HPI_TUNER_LEVEL {
766 HPI_TUNER_LEVEL_AVERAGE = 0,
767 HPI_TUNER_LEVEL_RAW = 1
768};
769
770/** Tuner Status Bits
771
772These bitfield values are returned by a call to HPI_Tuner_GetStatus().
773Multiple fields are returned from a single call.
774\ingroup tuner
775*/
776enum HPI_TUNER_STATUS_BITS {
777 HPI_TUNER_VIDEO_COLOR_PRESENT = 0x0001, /**< video color is present. */
778 HPI_TUNER_VIDEO_IS_60HZ = 0x0020, /**< 60 hz video detected. */
779 HPI_TUNER_VIDEO_HORZ_SYNC_MISSING = 0x0040, /**< video HSYNC is missing. */
780 HPI_TUNER_VIDEO_STATUS_VALID = 0x0100, /**< video status is valid. */
781 HPI_TUNER_PLL_LOCKED = 0x1000, /**< the tuner's PLL is locked. */
782 HPI_TUNER_FM_STEREO = 0x2000, /**< tuner reports back FM stereo. */
783 HPI_TUNER_DIGITAL = 0x0200, /**< tuner reports digital programming. */
784 HPI_TUNER_MULTIPROGRAM = 0x0400 /**< tuner reports multiple programs. */
785};
786
787/** Channel Modes
788Used for HPI_ChannelModeSet/Get()
789\ingroup channelmode
790*/
791enum HPI_CHANNEL_MODES {
792/** Left channel out = left channel in, Right channel out = right channel in. */
793 HPI_CHANNEL_MODE_NORMAL = 1,
794/** Left channel out = right channel in, Right channel out = left channel in. */
795 HPI_CHANNEL_MODE_SWAP = 2,
796/** Left channel out = left channel in, Right channel out = left channel in. */
797 HPI_CHANNEL_MODE_LEFT_TO_STEREO = 3,
798/** Left channel out = right channel in, Right channel out = right channel in.*/
799 HPI_CHANNEL_MODE_RIGHT_TO_STEREO = 4,
800/** Left channel out = (left channel in + right channel in)/2,
801 Right channel out = mute. */
802 HPI_CHANNEL_MODE_STEREO_TO_LEFT = 5,
803/** Left channel out = mute,
804 Right channel out = (right channel in + left channel in)/2. */
805 HPI_CHANNEL_MODE_STEREO_TO_RIGHT = 6,
806 HPI_CHANNEL_MODE_LAST = 6
807};
808
809/** SampleClock source values
810\ingroup sampleclock
811*/
812enum HPI_SAMPLECLOCK_SOURCES {
813/** The sampleclock output is derived from its local samplerate generator.
814 The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */
815 HPI_SAMPLECLOCK_SOURCE_LOCAL = 1,
816/** \deprecated Use HPI_SAMPLECLOCK_SOURCE_LOCAL instead */
817 HPI_SAMPLECLOCK_SOURCE_ADAPTER = 1,
818/** The adapter is clocked from a dedicated AES/EBU SampleClock input.*/
819 HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2,
820/** From external wordclock connector */
821 HPI_SAMPLECLOCK_SOURCE_WORD = 3,
822/** Board-to-board header */
823 HPI_SAMPLECLOCK_SOURCE_WORD_HEADER = 4,
824/** FUTURE - SMPTE clock. */
825 HPI_SAMPLECLOCK_SOURCE_SMPTE = 5,
826/** One of the aesebu inputs */
827 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT = 6,
828/** \deprecated The first aesebu input with a valid signal
829Superseded by separate Auto enable flag
830*/
831 HPI_SAMPLECLOCK_SOURCE_AESEBU_AUTO = 7,
832/** From a network interface e.g. Cobranet or Livewire at either 48 or 96kHz */
833 HPI_SAMPLECLOCK_SOURCE_NETWORK = 8,
834/** From previous adjacent module (ASI2416 only)*/
835 HPI_SAMPLECLOCK_SOURCE_PREV_MODULE = 10,
836/*! Update this if you add a new clock source.*/
837 HPI_SAMPLECLOCK_SOURCE_LAST = 10
838};
839
840/** Equalizer filter types. Used by HPI_ParametricEQ_SetBand()
841\ingroup parmeq
842*/
843enum HPI_FILTER_TYPE {
844 HPI_FILTER_TYPE_BYPASS = 0, /**< filter is turned off */
845
846 HPI_FILTER_TYPE_LOWSHELF = 1, /**< EQ low shelf */
847 HPI_FILTER_TYPE_HIGHSHELF = 2, /**< EQ high shelf */
848 HPI_FILTER_TYPE_EQ_BAND = 3, /**< EQ gain */
849
850 HPI_FILTER_TYPE_LOWPASS = 4, /**< standard low pass */
851 HPI_FILTER_TYPE_HIGHPASS = 5, /**< standard high pass */
852 HPI_FILTER_TYPE_BANDPASS = 6, /**< standard band pass */
853 HPI_FILTER_TYPE_BANDSTOP = 7 /**< standard band stop/notch */
854};
855
856/** Async Event sources
857\ingroup async
858*/
859enum ASYNC_EVENT_SOURCES {
860 HPI_ASYNC_EVENT_GPIO = 1, /**< GPIO event. */
861 HPI_ASYNC_EVENT_SILENCE = 2, /**< silence event detected. */
862 HPI_ASYNC_EVENT_TONE = 3 /**< tone event detected. */
863};
864/*******************************************/
865/** HPI Error codes
866
867Almost all HPI functions return an error code
868A return value of zero means there was no error.
869Otherwise one of these error codes is returned.
870Error codes can be converted to a descriptive string using HPI_GetErrorText()
871
872\note When a new error code is added HPI_GetErrorText() MUST be updated.
873\note Codes 1-100 are reserved for driver use
874\ingroup utility
875*/
876enum HPI_ERROR_CODES {
877 /** Message type does not exist. */
878 HPI_ERROR_INVALID_TYPE = 100,
879 /** Object type does not exist. */
880 HPI_ERROR_INVALID_OBJ = 101,
881 /** Function does not exist. */
882 HPI_ERROR_INVALID_FUNC = 102,
883 /** The specified object (adapter/Stream) does not exist. */
884 HPI_ERROR_INVALID_OBJ_INDEX = 103,
885 /** Trying to access an object that has not been opened yet. */
886 HPI_ERROR_OBJ_NOT_OPEN = 104,
887 /** Trying to open an already open object. */
888 HPI_ERROR_OBJ_ALREADY_OPEN = 105,
889 /** PCI, ISA resource not valid. */
890 HPI_ERROR_INVALID_RESOURCE = 106,
891 /** GetInfo call from SubSysFindAdapters failed. */
892 HPI_ERROR_SUBSYSFINDADAPTERS_GETINFO = 107,
893 /** Default response was never updated with actual error code. */
894 HPI_ERROR_INVALID_RESPONSE = 108,
895 /** wSize field of response was not updated,
896 indicating that the message was not processed. */
897 HPI_ERROR_PROCESSING_MESSAGE = 109,
898 /** The network did not respond in a timely manner. */
899 HPI_ERROR_NETWORK_TIMEOUT = 110,
900 /** An HPI handle is invalid (uninitialised?). */
901 HPI_ERROR_INVALID_HANDLE = 111,
902 /** A function or attribute has not been implemented yet. */
903 HPI_ERROR_UNIMPLEMENTED = 112,
904 /** There are too many clients attempting to access a network resource. */
905 HPI_ERROR_NETWORK_TOO_MANY_CLIENTS = 113,
906 /** Response buffer passed to HPI_Message was smaller than returned response */
907 HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL = 114,
908 /** The returned response did not match the sent message */
909 HPI_ERROR_RESPONSE_MISMATCH = 115,
910
911 /** Too many adapters.*/
912 HPI_ERROR_TOO_MANY_ADAPTERS = 200,
913 /** Bad adpater. */
914 HPI_ERROR_BAD_ADAPTER = 201,
915 /** Adapter number out of range or not set properly. */
916 HPI_ERROR_BAD_ADAPTER_NUMBER = 202,
917 /** 2 adapters with the same adapter number. */
918 HPI_DUPLICATE_ADAPTER_NUMBER = 203,
919 /** DSP code failed to bootload. */
920 HPI_ERROR_DSP_BOOTLOAD = 204,
921 /** Adapter failed DSP code self test. */
922 HPI_ERROR_DSP_SELFTEST = 205,
923 /** Couldn't find or open the DSP code file. */
924 HPI_ERROR_DSP_FILE_NOT_FOUND = 206,
925 /** Internal DSP hardware error. */
926 HPI_ERROR_DSP_HARDWARE = 207,
927 /** Could not allocate memory in DOS. */
928 HPI_ERROR_DOS_MEMORY_ALLOC = 208,
929 /** Could not allocate memory */
930 HPI_ERROR_MEMORY_ALLOC = 208,
931 /** Failed to correctly load/config PLD .*/
932 HPI_ERROR_PLD_LOAD = 209,
933 /** Unexpected end of file, block length too big etc. */
934 HPI_ERROR_DSP_FILE_FORMAT = 210,
935
936 /** Found but could not open DSP code file. */
937 HPI_ERROR_DSP_FILE_ACCESS_DENIED = 211,
938 /** First DSP code section header not found in DSP file. */
939 HPI_ERROR_DSP_FILE_NO_HEADER = 212,
940 /** File read operation on DSP code file failed. */
941 HPI_ERROR_DSP_FILE_READ_ERROR = 213,
942 /** DSP code for adapter family not found. */
943 HPI_ERROR_DSP_SECTION_NOT_FOUND = 214,
944 /** Other OS specific error opening DSP file. */
945 HPI_ERROR_DSP_FILE_OTHER_ERROR = 215,
946 /** Sharing violation opening DSP code file. */
947 HPI_ERROR_DSP_FILE_SHARING_VIOLATION = 216,
948 /** DSP code section header had size == 0. */
949 HPI_ERROR_DSP_FILE_NULL_HEADER = 217,
950
951 /** Base number for flash errors. */
952 HPI_ERROR_FLASH = 220,
953
954 /** Flash has bad checksum */
955 HPI_ERROR_BAD_CHECKSUM = (HPI_ERROR_FLASH + 1),
956 HPI_ERROR_BAD_SEQUENCE = (HPI_ERROR_FLASH + 2),
957 HPI_ERROR_FLASH_ERASE = (HPI_ERROR_FLASH + 3),
958 HPI_ERROR_FLASH_PROGRAM = (HPI_ERROR_FLASH + 4),
959 HPI_ERROR_FLASH_VERIFY = (HPI_ERROR_FLASH + 5),
960 HPI_ERROR_FLASH_TYPE = (HPI_ERROR_FLASH + 6),
961 HPI_ERROR_FLASH_START = (HPI_ERROR_FLASH + 7),
962
963 /** Reserved for OEMs. */
964 HPI_ERROR_RESERVED_1 = 290,
965
966 /** Stream does not exist. */
967 HPI_ERROR_INVALID_STREAM = 300,
968 /** Invalid compression format. */
969 HPI_ERROR_INVALID_FORMAT = 301,
970 /** Invalid format samplerate */
971 HPI_ERROR_INVALID_SAMPLERATE = 302,
972 /** Invalid format number of channels. */
973 HPI_ERROR_INVALID_CHANNELS = 303,
974 /** Invalid format bitrate. */
975 HPI_ERROR_INVALID_BITRATE = 304,
976 /** Invalid datasize used for stream read/write. */
977 HPI_ERROR_INVALID_DATASIZE = 305,
978 /** Stream buffer is full during stream write. */
979 HPI_ERROR_BUFFER_FULL = 306,
980 /** Stream buffer is empty during stream read. */
981 HPI_ERROR_BUFFER_EMPTY = 307,
982 /** Invalid datasize used for stream read/write. */
983 HPI_ERROR_INVALID_DATA_TRANSFER = 308,
984 /** Packet ordering error for stream read/write. */
985 HPI_ERROR_INVALID_PACKET_ORDER = 309,
986
987 /** Object can't do requested operation in its current
988 state, eg set format, change rec mux state while recording.*/
989 HPI_ERROR_INVALID_OPERATION = 310,
990
991 /** Where an SRG is shared amongst streams, an incompatible samplerate is one
992 that is different to any currently playing or recording stream. */
993 HPI_ERROR_INCOMPATIBLE_SAMPLERATE = 311,
994 /** Adapter mode is illegal.*/
995 HPI_ERROR_BAD_ADAPTER_MODE = 312,
996
997 /** There have been too many attempts to set the adapter's
998 capabilities (using bad keys), the card should be returned
999 to ASI if further capabilities updates are required */
1000 HPI_ERROR_TOO_MANY_CAPABILITY_CHANGE_ATTEMPTS = 313,
1001 /** Streams on different adapters cannot be grouped. */
1002 HPI_ERROR_NO_INTERADAPTER_GROUPS = 314,
1003 /** Streams on different DSPs cannot be grouped. */
1004 HPI_ERROR_NO_INTERDSP_GROUPS = 315,
1005
1006 /** Invalid mixer node for this adapter. */
1007 HPI_ERROR_INVALID_NODE = 400,
1008 /** Invalid control. */
1009 HPI_ERROR_INVALID_CONTROL = 401,
1010 /** Invalid control value was passed. */
1011 HPI_ERROR_INVALID_CONTROL_VALUE = 402,
1012 /** Control attribute not supported by this control. */
1013 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE = 403,
1014 /** Control is disabled. */
1015 HPI_ERROR_CONTROL_DISABLED = 404,
1016 /** I2C transaction failed due to a missing ACK. */
1017 HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405,
1018 /** Control attribute is valid, but not supported by this hardware. */
1019 HPI_ERROR_UNSUPPORTED_CONTROL_ATTRIBUTE = 406,
1020 /** Control is busy, or coming out of
1021 reset and cannot be accessed at this time. */
1022 HPI_ERROR_CONTROL_NOT_READY = 407,
1023
1024 /** Non volatile memory */
1025 HPI_ERROR_NVMEM_BUSY = 450,
1026 HPI_ERROR_NVMEM_FULL = 451,
1027 HPI_ERROR_NVMEM_FAIL = 452,
1028
1029 /** I2C */
1030 HPI_ERROR_I2C_MISSING_ACK = HPI_ERROR_CONTROL_I2C_MISSING_ACK,
1031 HPI_ERROR_I2C_BAD_ADR = 460,
1032
1033 /** Entity errors */
1034 HPI_ERROR_ENTITY_TYPE_MISMATCH = 470,
1035 HPI_ERROR_ENTITY_ITEM_COUNT = 471,
1036 HPI_ERROR_ENTITY_TYPE_INVALID = 472,
1037 HPI_ERROR_ENTITY_ROLE_INVALID = 473,
1038
1039 /* AES18 specific errors were 500..507 */
1040
1041 /** custom error to use for debugging */
1042 HPI_ERROR_CUSTOM = 600,
1043
1044 /** hpioct32.c can't obtain mutex */
1045 HPI_ERROR_MUTEX_TIMEOUT = 700,
1046
1047 /** errors from HPI backends have values >= this */
1048 HPI_ERROR_BACKEND_BASE = 900,
1049
1050 /** indicates a cached u16 value is invalid. */
1051 HPI_ERROR_ILLEGAL_CACHE_VALUE = 0xffff
1052};
1053
1054/** \defgroup maximums HPI maximum values
1055\{
1056*/
1057/** Maximum number of adapters per HPI sub-system
1058 WARNING: modifying this value changes the response structure size.*/
1059#define HPI_MAX_ADAPTERS 20
1060/** Maximum number of in or out streams per adapter */
1061#define HPI_MAX_STREAMS 16
1062#define HPI_MAX_CHANNELS 2 /* per stream */
1063#define HPI_MAX_NODES 8 /* per mixer ? */
1064#define HPI_MAX_CONTROLS 4 /* per node ? */
1065/** maximum number of ancillary bytes per MPEG frame */
1066#define HPI_MAX_ANC_BYTES_PER_FRAME (64)
1067#define HPI_STRING_LEN 16
1068
1069/** Velocity units */
1070#define HPI_OSTREAM_VELOCITY_UNITS 4096
1071/** OutStream timescale units */
1072#define HPI_OSTREAM_TIMESCALE_UNITS 10000
1073/** OutStream timescale passthrough - turns timescaling on in passthough mode */
1074#define HPI_OSTREAM_TIMESCALE_PASSTHROUGH 99999
1075
1076/**\}*/
1077
1078/* ////////////////////////////////////////////////////////////////////// */
1079/* STRUCTURES */
1080#ifndef DISABLE_PRAGMA_PACK1
1081#pragma pack(push, 1)
1082#endif
1083
1084/** Structure containing sample format information.
1085 See also HPI_FormatCreate().
1086 */
1087struct hpi_format {
1088 u32 sample_rate;
1089 /**< 11025, 32000, 44100 ... */
1090 u32 bit_rate; /**< for MPEG */
1091 u32 attributes;
1092 /**< Stereo/JointStereo/Mono */
1093 u16 mode_legacy;
1094 /**< Legacy ancillary mode or idle bit */
1095 u16 unused; /**< unused */
1096 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
1097 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */
1098};
1099
1100struct hpi_anc_frame {
1101 u32 valid_bits_in_this_frame;
1102 u8 b_data[HPI_MAX_ANC_BYTES_PER_FRAME];
1103};
1104
1105/** An object for containing a single async event.
1106*/
1107struct hpi_async_event {
1108 u16 event_type; /**< type of event. \sa async_event */
1109 u16 sequence; /**< sequence number, allows lost event detection */
1110 u32 state; /**< new state */
1111 u32 h_object; /**< handle to the object returning the event. */
1112 union {
1113 struct {
1114 u16 index; /**< GPIO bit index. */
1115 } gpio;
1116 struct {
1117 u16 node_index; /**< what node is the control on ? */
1118 u16 node_type; /**< what type of node is the control on ? */
1119 } control;
1120 } u;
1121};
1122
1123/*/////////////////////////////////////////////////////////////////////////// */
1124/* Public HPI Entity related definitions */
1125
1126struct hpi_entity;
1127
1128enum e_entity_type {
1129 entity_type_null,
1130 entity_type_sequence, /* sequence of potentially heterogeneous TLV entities */
1131
1132 entity_type_reference, /* refers to a TLV entity or NULL */
1133
1134 entity_type_int, /* 32 bit */
1135 entity_type_float, /* ieee754 binary 32 bit encoding */
1136 entity_type_double,
1137
1138 entity_type_cstring,
1139 entity_type_octet,
1140 entity_type_ip4_address,
1141 entity_type_ip6_address,
1142 entity_type_mac_address,
1143
1144 LAST_ENTITY_TYPE
1145};
1146
1147enum e_entity_role {
1148 entity_role_null,
1149 entity_role_value,
1150 entity_role_classname,
1151
1152 entity_role_units,
1153 entity_role_flags,
1154 entity_role_range,
1155
1156 entity_role_mapping,
1157 entity_role_enum,
1158
1159 entity_role_instance_of,
1160 entity_role_depends_on,
1161 entity_role_member_of_group,
1162 entity_role_value_constraint,
1163 entity_role_parameter_port,
1164
1165 entity_role_block,
1166 entity_role_node_group,
1167 entity_role_audio_port,
1168 entity_role_clock_port,
1169 LAST_ENTITY_ROLE
1170};
1171
1172/* skip host side function declarations for
1173 DSP compile and documentation extraction */
1174
1175struct hpi_hsubsys {
1176 int not_really_used;
1177};
1178
1179#ifndef DISABLE_PRAGMA_PACK1
1180#pragma pack(pop)
1181#endif
1182
1183/*////////////////////////////////////////////////////////////////////////// */
1184/* HPI FUNCTIONS */
1185
1186/*/////////////////////////// */
1187/* DATA and FORMAT and STREAM */
1188
1189u16 hpi_stream_estimate_buffer_size(struct hpi_format *pF,
1190 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size);
1191
1192/*/////////// */
1193/* SUB SYSTEM */
1194struct hpi_hsubsys *hpi_subsys_create(void
1195 );
1196
1197void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys);
1198
1199u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys,
1200 u32 *pversion);
1201
1202u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
1203 u32 *pversion_ex);
1204
1205u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion,
1206 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1207
1208u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
1209 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length);
1210
1211u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
1212 int *pn_num_adapters);
1213
1214u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator,
1215 u32 *padapter_index, u16 *pw_adapter_type);
1216
1217u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass);
1218
1219u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys,
1220 const char *sz_interface);
1221
1222/*///////// */
1223/* ADAPTER */
1224
1225u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index);
1226
1227u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index);
1228
1229u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys,
1230 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams,
1231 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type);
1232
1233u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys,
1234 u16 adapter_index, u16 module_index, u16 *pw_num_outputs,
1235 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number,
1236 u16 *pw_module_type, u32 *ph_module);
1237
1238u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys,
1239 u16 adapter_index, u32 adapter_mode);
1240
1241u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
1242 u16 adapter_index, u32 adapter_mode, u16 query_or_set);
1243
1244u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
1245 u16 adapter_index, u32 *padapter_mode);
1246
1247u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys,
1248 u16 adapter_index, u16 *assert_present, char *psz_assert,
1249 u16 *pw_line_number);
1250
1251u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
1252 u16 adapter_index, u16 *assert_present, char *psz_assert,
1253 u32 *pline_number, u16 *pw_assert_on_dsp);
1254
1255u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
1256 u16 adapter_index, u16 assert_id);
1257
1258u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
1259 u16 adapter_index, u16 capability, u32 key);
1260
1261u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
1262 u16 adapter_index);
1263
1264u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
1265 u16 adapter_index, u32 dsp_address, char *p_bytes, int *count_bytes);
1266
1267u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
1268 u16 adapter_index, u16 property, u16 paramter1, u16 paramter2);
1269
1270u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
1271 u16 adapter_index, u16 property, u16 *pw_paramter1,
1272 u16 *pw_paramter2);
1273
1274u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
1275 u16 adapter_index, u16 index, u16 what_to_enumerate,
1276 u16 property_index, u32 *psetting);
1277
1278/*////////////// */
1279/* NonVol Memory */
1280u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1281 u32 *ph_nv_memory, u16 *pw_size_in_bytes);
1282
1283u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
1284 u32 h_nv_memory, u16 index, u16 *pw_data);
1285
1286u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
1287 u32 h_nv_memory, u16 index, u16 data);
1288
1289/*////////////// */
1290/* Digital I/O */
1291u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1292 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits);
1293
1294u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1295 u16 bit_index, u16 *pw_bit_data);
1296
1297u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1298 u16 aw_all_bit_data[4]
1299 );
1300
1301u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1302 u16 bit_index, u16 bit_data);
1303
1304u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
1305 u16 aw_all_bit_data[4]
1306 );
1307
1308/**********************/
1309/* Async Event Object */
1310/**********************/
1311u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
1312 u16 adapter_index, u32 *ph_async);
1313
1314u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async);
1315
1316u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
1317 u16 maximum_events, struct hpi_async_event *p_events,
1318 u16 *pw_number_returned);
1319
1320u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys,
1321 u32 h_async, u16 *pw_count);
1322
1323u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async,
1324 u16 maximum_events, struct hpi_async_event *p_events,
1325 u16 *pw_number_returned);
1326
1327/*/////////// */
1328/* WATCH-DOG */
1329u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1330 u32 *ph_watchdog);
1331
1332u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog,
1333 u32 time_millisec);
1334
1335u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog);
1336
1337/**************/
1338/* OUT STREAM */
1339/**************/
1340u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1341 u16 outstream_index, u32 *ph_outstream);
1342
1343u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1344
1345u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1346 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play,
1347 u32 *psamples_played, u32 *pauxiliary_data_to_play);
1348
1349u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys,
1350 u32 h_outstream, const u8 *pb_write_buf, u32 bytes_to_write,
1351 const struct hpi_format *p_format);
1352
1353u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1354
1355u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys,
1356 u32 h_outstream);
1357
1358u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1359
1360u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys,
1361 u32 h_outstream);
1362
1363u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream);
1364
1365u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys,
1366 u32 h_outstream, struct hpi_format *p_format);
1367
1368u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys,
1369 u32 h_outstream, struct hpi_format *p_format);
1370
1371u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys,
1372 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample);
1373
1374u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys,
1375 u32 h_outstream, short velocity);
1376
1377u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1378 u32 h_outstream, u16 mode);
1379
1380u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1381 u32 h_outstream, u32 *pframes_available);
1382
1383u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
1384 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer,
1385 u32 anc_frame_buffer_size_in_bytes,
1386 u32 number_of_ancillary_frames_to_read);
1387
1388u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys,
1389 u32 h_outstream, u32 time_scaleX10000);
1390
1391u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1392 u32 h_outstream, u32 size_in_bytes);
1393
1394u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1395 u32 h_outstream);
1396
1397u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1398 u32 h_outstream, u32 h_stream);
1399
1400u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1401 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map);
1402
1403u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys,
1404 u32 h_outstream);
1405
1406/*////////// */
1407/* IN_STREAM */
1408u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1409 u16 instream_index, u32 *ph_instream);
1410
1411u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1412
1413u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys,
1414 u32 h_instream, const struct hpi_format *p_format);
1415
1416u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys,
1417 u32 h_instream, const struct hpi_format *p_format);
1418
1419u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream,
1420 u8 *pb_read_buf, u32 bytes_to_read);
1421
1422u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1423
1424u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys,
1425 u32 h_instream);
1426
1427u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1428
1429u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream);
1430
1431u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1432 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded,
1433 u32 *psamples_recorded, u32 *pauxiliary_data_recorded);
1434
1435u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1436 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment,
1437 u16 idle_bit);
1438
1439u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1440 u32 h_instream, u32 *pframe_space);
1441
1442u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1443 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer,
1444 u32 anc_frame_buffer_size_in_bytes,
1445 u32 number_of_ancillary_frames_to_write);
1446
1447u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1448 u32 h_instream, u32 size_in_bytes);
1449
1450u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1451 u32 h_instream);
1452
1453u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1454 u32 h_instream, u32 h_stream);
1455
1456u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1457 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map);
1458
1459u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys,
1460 u32 h_instream);
1461
1462/*********/
1463/* MIXER */
1464/*********/
1465u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1466 u32 *ph_mixer);
1467
1468u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer);
1469
1470u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1471 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type,
1472 u16 dst_node_type_index, u16 control_type, u32 *ph_control);
1473
1474u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys,
1475 u32 h_mixer, u16 control_index, u16 *pw_src_node_type,
1476 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index,
1477 u16 *pw_control_type, u32 *ph_control);
1478
1479u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1480 enum HPI_MIXER_STORE_COMMAND command, u16 index);
1481/*************************/
1482/* mixer CONTROLS */
1483/*************************/
1484/*************************/
1485/* volume control */
1486/*************************/
1487u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1488 short an_gain0_01dB[HPI_MAX_CHANNELS]
1489 );
1490
1491u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1492 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1493 );
1494
1495#define hpi_volume_get_range hpi_volume_query_range
1496u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1497 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB);
1498
1499u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys,
1500 const u32 h_volume, u32 *p_channels);
1501
1502u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1503 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms);
1504
1505u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
1506 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS],
1507 u32 duration_ms, u16 profile);
1508
1509/*************************/
1510/* level control */
1511/*************************/
1512u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1513 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB);
1514
1515u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1516 short an_gain0_01dB[HPI_MAX_CHANNELS]
1517 );
1518
1519u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1520 short an_gain0_01dB_out[HPI_MAX_CHANNELS]
1521 );
1522
1523/*************************/
1524/* meter control */
1525/*************************/
1526u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys,
1527 const u32 h_meter, u32 *p_channels);
1528
1529u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1530 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1531 );
1532
1533u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1534 short an_peak0_01dB_out[HPI_MAX_CHANNELS]
1535 );
1536
1537u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
1538 u32 h_control, u16 attack, u16 decay);
1539
1540u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
1541 u32 h_control, u16 attack, u16 decay);
1542
1543u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
1544 u32 h_control, u16 *attack, u16 *decay);
1545
1546u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
1547 u32 h_control, u16 *attack, u16 *decay);
1548
1549/*************************/
1550/* channel mode control */
1551/*************************/
1552u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys,
1553 const u32 h_mode, const u32 index, u16 *pw_mode);
1554
1555u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1556 u16 mode);
1557
1558u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1559 u16 *mode);
1560
1561/*************************/
1562/* Tuner control */
1563/*************************/
1564u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys,
1565 const u32 h_tuner, const u32 index, u16 *pw_band);
1566
1567u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1568 u16 band);
1569
1570u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1571 u16 *pw_band);
1572
1573u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys,
1574 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq);
1575
1576u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys,
1577 u32 h_control, u32 freq_ink_hz);
1578
1579u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys,
1580 u32 h_control, u32 *pw_freq_ink_hz);
1581
1582u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1583 short *pw_level);
1584
1585u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys,
1586 u32 h_control, short *pw_level);
1587
1588u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys,
1589 const u32 h_tuner, const u32 index, u16 *pw_gain);
1590
1591u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1592 short gain);
1593
1594u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1595 short *pn_gain);
1596
1597u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1598 u16 *pw_status_mask, u16 *pw_status);
1599
1600u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1601 u32 mode, u32 value);
1602
1603u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1604 u32 mode, u32 *pn_value);
1605
1606u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1607 char *p_rds_data);
1608
1609u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys,
1610 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis);
1611
1612u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys,
1613 u32 h_control, u32 deemphasis);
1614u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys,
1615 u32 h_control, u32 *pdeemphasis);
1616
1617u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys,
1618 const u32 h_tuner, u32 *pbitmap_program);
1619
1620u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1621 u32 program);
1622
1623u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1624 u32 *pprogram);
1625
1626u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys,
1627 u32 h_control, char *psz_dsp_version, const u32 string_size);
1628
1629u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys,
1630 u32 h_control, char *psz_sdk_version, const u32 string_size);
1631
1632u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys,
1633 u32 h_control, u32 *pquality);
1634
1635/****************************/
1636/* PADs control */
1637/****************************/
1638
1639u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys,
1640 u32 h_control, char *psz_string, const u32 string_length);
1641
1642u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1643 char *psz_string, const u32 string_length);
1644
1645u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1646 char *psz_string, const u32 string_length);
1647
1648u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1649 char *psz_string, const u32 string_length);
1650
1651u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys,
1652 u32 h_control, u32 *ppTY);
1653
1654u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1655 u32 *ppI);
1656
1657u16 HPI_PAD__get_program_type_string(const struct hpi_hsubsys *ph_subsys,
1658 u32 h_control, const u32 data_type, const u32 pTY, char *psz_string,
1659 const u32 string_length);
1660
1661/****************************/
1662/* AES/EBU Receiver control */
1663/****************************/
1664u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys,
1665 const u32 h_aes_rx, const u32 index, u16 *pw_format);
1666
1667u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys,
1668 u32 h_control, u16 source);
1669
1670u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys,
1671 u32 h_control, u16 *pw_source);
1672
1673u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1674 u32 h_control, u32 *psample_rate);
1675
1676u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys,
1677 u32 h_control, u16 index, u16 *pw_data);
1678
1679u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys
1680 *ph_subsys, u32 h_control, u16 index, u16 *pw_data);
1681
1682u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys,
1683 u32 h_control, u16 *pw_error_data);
1684
1685/*******************************/
1686/* AES/EBU Transmitter control */
1687/*******************************/
1688u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys
1689 *ph_subsys, u32 h_control, u32 sample_rate);
1690
1691u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys,
1692 u32 h_control, u16 index, u16 data);
1693
1694u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys
1695 *ph_subsys, u32 h_control, u16 index, u16 data);
1696
1697u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys
1698 *ph_subsys, u32 h_control, u16 index, u16 *pw_data);
1699
1700u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys,
1701 const u32 h_aes_tx, const u32 index, u16 *pw_format);
1702
1703u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys,
1704 u32 h_control, u16 output_format);
1705
1706u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys,
1707 u32 h_control, u16 *pw_output_format);
1708
1709/***********************/
1710/* multiplexer control */
1711/***********************/
1712u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys,
1713 u32 h_control, u16 source_node_type, u16 source_node_index);
1714
1715u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys,
1716 u32 h_control, u16 *source_node_type, u16 *source_node_index);
1717
1718u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys,
1719 u32 h_control, u16 index, u16 *source_node_type,
1720 u16 *source_node_index);
1721
1722/***************/
1723/* VOX control */
1724/***************/
1725u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1726 short an_gain0_01dB);
1727
1728u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1729 short *an_gain0_01dB);
1730
1731/*********************/
1732/* Bitstream control */
1733/*********************/
1734u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys,
1735 u32 h_control, u16 edge_type);
1736
1737u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys,
1738 u32 h_control, u16 polarity);
1739
1740u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys,
1741 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity);
1742
1743/***********************/
1744/* SampleClock control */
1745/***********************/
1746
1747u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys,
1748 const u32 h_clock, const u32 index, u16 *pw_source);
1749
1750u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys,
1751 u32 h_control, u16 source);
1752
1753u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys,
1754 u32 h_control, u16 *pw_source);
1755
1756u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys,
1757 const u32 h_clock, const u32 index, const u32 source,
1758 u16 *pw_source_index);
1759
1760u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys,
1761 u32 h_control, u16 source_index);
1762
1763u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys,
1764 u32 h_control, u16 *pw_source_index);
1765
1766u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1767 u32 h_control, u32 *psample_rate);
1768
1769u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys,
1770 const u32 h_clock, const u32 index, u32 *psource);
1771
1772u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys,
1773 u32 h_control, u32 sample_rate);
1774
1775u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys,
1776 u32 h_control, u32 *psample_rate);
1777
1778u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys,
1779 u32 h_control, u32 enable);
1780
1781u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys,
1782 u32 h_control, u32 *penable);
1783
1784u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
1785 u32 h_control, u32 lock);
1786
1787u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
1788 u32 h_control, u32 *plock);
1789
1790/***********************/
1791/* Microphone control */
1792/***********************/
1793u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys,
1794 u32 h_control, u16 on_off);
1795
1796u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys,
1797 u32 h_control, u16 *pw_on_off);
1798
1799/*******************************
1800 Parametric Equalizer control
1801*******************************/
1802u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys,
1803 u32 h_control, u16 *pw_number_of_bands, u16 *pw_enabled);
1804
1805u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys,
1806 u32 h_control, u16 on_off);
1807
1808u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
1809 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100,
1810 short gain0_01dB);
1811
1812u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
1813 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz,
1814 short *pnQ100, short *pn_gain0_01dB);
1815
1816u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
1817 u32 h_control, u16 index, short coeffs[5]
1818 );
1819
1820/*******************************
1821 Compressor Expander control
1822*******************************/
1823
1824u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1825 u16 attack, u16 decay, short ratio100, short threshold0_01dB,
1826 short makeup_gain0_01dB);
1827
1828u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1829 u16 *pw_attack, u16 *pw_decay, short *pw_ratio100,
1830 short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB);
1831
1832/*******************************
1833 Cobranet HMI control
1834*******************************/
1835u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1836 u32 hmi_address, u32 byte_count, u8 *pb_data);
1837
1838u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1839 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data);
1840
1841u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1842 u32 h_control, u32 *pstatus, u32 *preadable_size,
1843 u32 *pwriteable_size);
1844
1845/*Read the current IP address
1846*/
1847u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
1848 u32 h_control, u32 *pi_paddress);
1849
1850/* Write the current IP address
1851*/
1852u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys,
1853 u32 h_control, u32 i_paddress);
1854
1855/* Read the static IP address
1856*/
1857u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1858 u32 h_control, u32 *pi_paddress);
1859
1860/* Write the static IP address
1861*/
1862u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
1863 u32 h_control, u32 i_paddress);
1864
1865/* Read the MAC address
1866*/
1867u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
1868 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs);
1869
1870/*******************************
1871 Tone Detector control
1872*******************************/
1873u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys, u32 hC,
1874 u32 *state);
1875
1876u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys, u32 hC,
1877 u32 enable);
1878
1879u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys, u32 hC,
1880 u32 *enable);
1881
1882u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
1883 u32 hC, u32 event_enable);
1884
1885u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
1886 u32 hC, u32 *event_enable);
1887
1888u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
1889 u32 hC, int threshold);
1890
1891u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
1892 u32 hC, int *threshold);
1893
1894u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys,
1895 u32 hC, u32 index, u32 *frequency);
1896
1897/*******************************
1898 Silence Detector control
1899*******************************/
1900u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
1901 u32 hC, u32 *state);
1902
1903u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
1904 u32 hC, u32 enable);
1905
1906u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
1907 u32 hC, u32 *enable);
1908
1909u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
1910 u32 hC, u32 event_enable);
1911
1912u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
1913 u32 hC, u32 *event_enable);
1914
1915u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys,
1916 u32 hC, u32 delay);
1917
1918u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys,
1919 u32 hC, u32 *delay);
1920
1921u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
1922 u32 hC, int threshold);
1923
1924u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
1925 u32 hC, int *threshold);
1926
1927/*******************************
1928 Universal control
1929*******************************/
1930u16 hpi_entity_find_next(struct hpi_entity *container_entity,
1931 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
1932 struct hpi_entity **current_match);
1933
1934u16 hpi_entity_copy_value_from(struct hpi_entity *entity,
1935 enum e_entity_type type, size_t item_count, void *value_dst_p);
1936
1937u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type,
1938 size_t *items, enum e_entity_role *role, void **value);
1939
1940u16 hpi_entity_alloc_and_pack(const enum e_entity_type type,
1941 const size_t item_count, const enum e_entity_role role, void *value,
1942 struct hpi_entity **entity);
1943
1944void hpi_entity_free(struct hpi_entity *entity);
1945
1946u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC,
1947 struct hpi_entity **info);
1948
1949u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC,
1950 struct hpi_entity **value);
1951
1952u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC,
1953 struct hpi_entity *value);
1954
1955/*/////////// */
1956/* DSP CLOCK */
1957/*/////////// */
1958u16 hpi_clock_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1959 u32 *ph_dsp_clock);
1960
1961u16 hpi_clock_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock,
1962 u16 hour, u16 minute, u16 second, u16 milli_second);
1963
1964u16 hpi_clock_get_time(const struct hpi_hsubsys *ph_subsys, u32 h_clock,
1965 u16 *pw_hour, u16 *pw_minute, u16 *pw_second, u16 *pw_milli_second);
1966
1967/*/////////// */
1968/* PROFILE */
1969/*/////////// */
1970u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
1971 u16 adapter_index, u16 profile_index, u32 *ph_profile,
1972 u16 *pw_max_profiles);
1973
1974u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
1975 u16 index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
1976 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds);
1977
1978u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile);
1979
1980u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile);
1981
1982u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
1983 u16 index, char *sz_profile_name, u16 profile_name_length);
1984
1985u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys,
1986 u32 h_profile, u32 *putilization);
1987
1988/*//////////////////// */
1989/* UTILITY functions */
1990
1991u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
1992 u32 sample_rate, u32 bit_rate, u32 attributes);
1993
1994/* Until it's verified, this function is for Windows OSs only */
1995
1996#endif /*_H_HPI_ */
1997/*
1998///////////////////////////////////////////////////////////////////////////////
1999// See CVS for history. Last complete set in rev 1.146
2000////////////////////////////////////////////////////////////////////////////////
2001*/
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c
new file mode 100644
index 000000000000..839ecb2e4b64
--- /dev/null
+++ b/sound/pci/asihpi/hpi6000.c
@@ -0,0 +1,1840 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) for AudioScience ASI6200 series adapters.
20 These PCI bus adapters are based on the TI C6711 DSP.
21
22 Exported functions:
23 void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
24
25 #defines
26 HIDE_PCI_ASSERTS to show the PCI asserts
27 PROFILE_DSP2 get profile data from DSP2 if present (instead of DSP 1)
28
29(C) Copyright AudioScience Inc. 1998-2003
30*******************************************************************************/
31#define SOURCEFILE_NAME "hpi6000.c"
32
33#include "hpi_internal.h"
34#include "hpimsginit.h"
35#include "hpidebug.h"
36#include "hpi6000.h"
37#include "hpidspcd.h"
38#include "hpicmn.h"
39
40#define HPI_HIF_BASE (0x00000200) /* start of C67xx internal RAM */
41#define HPI_HIF_ADDR(member) \
42 (HPI_HIF_BASE + offsetof(struct hpi_hif_6000, member))
43#define HPI_HIF_ERROR_MASK 0x4000
44
45/* HPI6000 specific error codes */
46
47#define HPI6000_ERROR_BASE 900
48#define HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT 901
49#define HPI6000_ERROR_MSG_RESP_SEND_MSG_ACK 902
50#define HPI6000_ERROR_MSG_RESP_GET_RESP_ACK 903
51#define HPI6000_ERROR_MSG_GET_ADR 904
52#define HPI6000_ERROR_RESP_GET_ADR 905
53#define HPI6000_ERROR_MSG_RESP_BLOCKWRITE32 906
54#define HPI6000_ERROR_MSG_RESP_BLOCKREAD32 907
55#define HPI6000_ERROR_MSG_INVALID_DSP_INDEX 908
56#define HPI6000_ERROR_CONTROL_CACHE_PARAMS 909
57
58#define HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT 911
59#define HPI6000_ERROR_SEND_DATA_ACK 912
60#define HPI6000_ERROR_SEND_DATA_ADR 913
61#define HPI6000_ERROR_SEND_DATA_TIMEOUT 914
62#define HPI6000_ERROR_SEND_DATA_CMD 915
63#define HPI6000_ERROR_SEND_DATA_WRITE 916
64#define HPI6000_ERROR_SEND_DATA_IDLECMD 917
65#define HPI6000_ERROR_SEND_DATA_VERIFY 918
66
67#define HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT 921
68#define HPI6000_ERROR_GET_DATA_ACK 922
69#define HPI6000_ERROR_GET_DATA_CMD 923
70#define HPI6000_ERROR_GET_DATA_READ 924
71#define HPI6000_ERROR_GET_DATA_IDLECMD 925
72
73#define HPI6000_ERROR_CONTROL_CACHE_ADDRLEN 951
74#define HPI6000_ERROR_CONTROL_CACHE_READ 952
75#define HPI6000_ERROR_CONTROL_CACHE_FLUSH 953
76
77#define HPI6000_ERROR_MSG_RESP_GETRESPCMD 961
78#define HPI6000_ERROR_MSG_RESP_IDLECMD 962
79#define HPI6000_ERROR_MSG_RESP_BLOCKVERIFY32 963
80
81/* adapter init errors */
82#define HPI6000_ERROR_UNHANDLED_SUBSYS_ID 930
83
84/* can't access PCI2040 */
85#define HPI6000_ERROR_INIT_PCI2040 931
86/* can't access DSP HPI i/f */
87#define HPI6000_ERROR_INIT_DSPHPI 932
88/* can't access internal DSP memory */
89#define HPI6000_ERROR_INIT_DSPINTMEM 933
90/* can't access SDRAM - test#1 */
91#define HPI6000_ERROR_INIT_SDRAM1 934
92/* can't access SDRAM - test#2 */
93#define HPI6000_ERROR_INIT_SDRAM2 935
94
95#define HPI6000_ERROR_INIT_VERIFY 938
96
97#define HPI6000_ERROR_INIT_NOACK 939
98
99#define HPI6000_ERROR_INIT_PLDTEST1 941
100#define HPI6000_ERROR_INIT_PLDTEST2 942
101
102/* local defines */
103
104#define HIDE_PCI_ASSERTS
105#define PROFILE_DSP2
106
107/* for PCI2040 i/f chip */
108/* HPI CSR registers */
109/* word offsets from CSR base */
110/* use when io addresses defined as u32 * */
111
112#define INTERRUPT_EVENT_SET 0
113#define INTERRUPT_EVENT_CLEAR 1
114#define INTERRUPT_MASK_SET 2
115#define INTERRUPT_MASK_CLEAR 3
116#define HPI_ERROR_REPORT 4
117#define HPI_RESET 5
118#define HPI_DATA_WIDTH 6
119
120#define MAX_DSPS 2
121/* HPI registers, spaced 8K bytes = 2K words apart */
122#define DSP_SPACING 0x800
123
124#define CONTROL 0x0000
125#define ADDRESS 0x0200
126#define DATA_AUTOINC 0x0400
127#define DATA 0x0600
128
129#define TIMEOUT 500000
130
131struct dsp_obj {
132 __iomem u32 *prHPI_control;
133 __iomem u32 *prHPI_address;
134 __iomem u32 *prHPI_data;
135 __iomem u32 *prHPI_data_auto_inc;
136 char c_dsp_rev; /*A, B */
137 u32 control_cache_address_on_dsp;
138 u32 control_cache_length_on_dsp;
139 struct hpi_adapter_obj *pa_parent_adapter;
140};
141
142struct hpi_hw_obj {
143 __iomem u32 *dw2040_HPICSR;
144 __iomem u32 *dw2040_HPIDSP;
145
146 u16 num_dsp;
147 struct dsp_obj ado[MAX_DSPS];
148
149 u32 message_buffer_address_on_dsp;
150 u32 response_buffer_address_on_dsp;
151 u32 pCI2040HPI_error_count;
152
153 struct hpi_control_cache_single control_cache[HPI_NMIXER_CONTROLS];
154 struct hpi_control_cache *p_cache;
155};
156
157static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
158 u16 dsp_index, u32 hpi_address, u32 *source, u32 count);
159static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
160 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count);
161
162static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code);
164static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
165 u16 read_or_write);
166#define H6READ 1
167#define H6WRITE 0
168
169static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
170 struct hpi_message *phm);
171static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
172 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr);
173
174static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
175 struct hpi_response *phr);
176
177static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
178 u32 ack_value);
179
180static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
181 u16 dsp_index, u32 host_cmd);
182
183static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo);
184
185static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
186 struct hpi_message *phm, struct hpi_response *phr);
187
188static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
189 struct hpi_message *phm, struct hpi_response *phr);
190
191static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data);
192
193static u32 hpi_read_word(struct dsp_obj *pdo, u32 address);
194
195static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
196 u32 length);
197
198static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
199 u32 length);
200
201static void subsys_create_adapter(struct hpi_message *phm,
202 struct hpi_response *phr);
203
204static void subsys_delete_adapter(struct hpi_message *phm,
205 struct hpi_response *phr);
206
207static void adapter_get_asserts(struct hpi_adapter_obj *pao,
208 struct hpi_message *phm, struct hpi_response *phr);
209
210static short create_adapter_obj(struct hpi_adapter_obj *pao,
211 u32 *pos_error_code);
212
213/* local globals */
214
215static u16 gw_pci_read_asserts; /* used to count PCI2040 errors */
216static u16 gw_pci_write_asserts; /* used to count PCI2040 errors */
217
218static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
219{
220
221 switch (phm->function) {
222 case HPI_SUBSYS_OPEN:
223 case HPI_SUBSYS_CLOSE:
224 case HPI_SUBSYS_GET_INFO:
225 case HPI_SUBSYS_DRIVER_UNLOAD:
226 case HPI_SUBSYS_DRIVER_LOAD:
227 case HPI_SUBSYS_FIND_ADAPTERS:
228 /* messages that should not get here */
229 phr->error = HPI_ERROR_UNIMPLEMENTED;
230 break;
231 case HPI_SUBSYS_CREATE_ADAPTER:
232 subsys_create_adapter(phm, phr);
233 break;
234 case HPI_SUBSYS_DELETE_ADAPTER:
235 subsys_delete_adapter(phm, phr);
236 break;
237 default:
238 phr->error = HPI_ERROR_INVALID_FUNC;
239 break;
240 }
241}
242
243static void control_message(struct hpi_adapter_obj *pao,
244 struct hpi_message *phm, struct hpi_response *phr)
245{
246
247 switch (phm->function) {
248 case HPI_CONTROL_GET_STATE:
249 if (pao->has_control_cache) {
250 u16 err;
251 err = hpi6000_update_control_cache(pao, phm);
252
253 if (err) {
254 phr->error = err;
255 break;
256 }
257
258 if (hpi_check_control_cache(((struct hpi_hw_obj *)
259 pao->priv)->p_cache, phm,
260 phr))
261 break;
262 }
263 hw_message(pao, phm, phr);
264 break;
265 case HPI_CONTROL_GET_INFO:
266 hw_message(pao, phm, phr);
267 break;
268 case HPI_CONTROL_SET_STATE:
269 hw_message(pao, phm, phr);
270 hpi_sync_control_cache(((struct hpi_hw_obj *)pao->priv)->
271 p_cache, phm, phr);
272 break;
273 default:
274 phr->error = HPI_ERROR_INVALID_FUNC;
275 break;
276 }
277}
278
279static void adapter_message(struct hpi_adapter_obj *pao,
280 struct hpi_message *phm, struct hpi_response *phr)
281{
282 switch (phm->function) {
283 case HPI_ADAPTER_GET_INFO:
284 hw_message(pao, phm, phr);
285 break;
286 case HPI_ADAPTER_GET_ASSERT:
287 adapter_get_asserts(pao, phm, phr);
288 break;
289 case HPI_ADAPTER_OPEN:
290 case HPI_ADAPTER_CLOSE:
291 case HPI_ADAPTER_TEST_ASSERT:
292 case HPI_ADAPTER_SELFTEST:
293 case HPI_ADAPTER_GET_MODE:
294 case HPI_ADAPTER_SET_MODE:
295 case HPI_ADAPTER_FIND_OBJECT:
296 case HPI_ADAPTER_GET_PROPERTY:
297 case HPI_ADAPTER_SET_PROPERTY:
298 case HPI_ADAPTER_ENUM_PROPERTY:
299 hw_message(pao, phm, phr);
300 break;
301 default:
302 phr->error = HPI_ERROR_INVALID_FUNC;
303 break;
304 }
305}
306
307static void outstream_message(struct hpi_adapter_obj *pao,
308 struct hpi_message *phm, struct hpi_response *phr)
309{
310 switch (phm->function) {
311 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
312 case HPI_OSTREAM_HOSTBUFFER_FREE:
313 /* Don't let these messages go to the HW function because
314 * they're called without allocating the spinlock.
315 * For the HPI6000 adapters the HW would return
316 * HPI_ERROR_INVALID_FUNC anyway.
317 */
318 phr->error = HPI_ERROR_INVALID_FUNC;
319 break;
320 default:
321 hw_message(pao, phm, phr);
322 return;
323 }
324}
325
326static void instream_message(struct hpi_adapter_obj *pao,
327 struct hpi_message *phm, struct hpi_response *phr)
328{
329
330 switch (phm->function) {
331 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
332 case HPI_ISTREAM_HOSTBUFFER_FREE:
333 /* Don't let these messages go to the HW function because
334 * they're called without allocating the spinlock.
335 * For the HPI6000 adapters the HW would return
336 * HPI_ERROR_INVALID_FUNC anyway.
337 */
338 phr->error = HPI_ERROR_INVALID_FUNC;
339 break;
340 default:
341 hw_message(pao, phm, phr);
342 return;
343 }
344}
345
346/************************************************************************/
347/** HPI_6000()
348 * Entry point from HPIMAN
349 * All calls to the HPI start here
350 */
351void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
352{
353 struct hpi_adapter_obj *pao = NULL;
354
355 /* subsytem messages get executed by every HPI. */
356 /* All other messages are ignored unless the adapter index matches */
357 /* an adapter in the HPI */
358 HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->object, phm->function);
359
360 /* if Dsp has crashed then do not communicate with it any more */
361 if (phm->object != HPI_OBJ_SUBSYSTEM) {
362 pao = hpi_find_adapter(phm->adapter_index);
363 if (!pao) {
364 HPI_DEBUG_LOG(DEBUG,
365 " %d,%d refused, for another HPI?\n",
366 phm->object, phm->function);
367 return;
368 }
369
370 if (pao->dsp_crashed >= 10) {
371 hpi_init_response(phr, phm->object, phm->function,
372 HPI_ERROR_DSP_HARDWARE);
373 HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n",
374 phm->object, phm->function);
375 return;
376 }
377 }
378 /* Init default response including the size field */
379 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
380 hpi_init_response(phr, phm->object, phm->function,
381 HPI_ERROR_PROCESSING_MESSAGE);
382
383 switch (phm->type) {
384 case HPI_TYPE_MESSAGE:
385 switch (phm->object) {
386 case HPI_OBJ_SUBSYSTEM:
387 subsys_message(phm, phr);
388 break;
389
390 case HPI_OBJ_ADAPTER:
391 phr->size =
392 sizeof(struct hpi_response_header) +
393 sizeof(struct hpi_adapter_res);
394 adapter_message(pao, phm, phr);
395 break;
396
397 case HPI_OBJ_CONTROL:
398 control_message(pao, phm, phr);
399 break;
400
401 case HPI_OBJ_OSTREAM:
402 outstream_message(pao, phm, phr);
403 break;
404
405 case HPI_OBJ_ISTREAM:
406 instream_message(pao, phm, phr);
407 break;
408
409 default:
410 hw_message(pao, phm, phr);
411 break;
412 }
413 break;
414
415 default:
416 phr->error = HPI_ERROR_INVALID_TYPE;
417 break;
418 }
419}
420
421/************************************************************************/
422/* SUBSYSTEM */
423
424/* create an adapter object and initialise it based on resource information
425 * passed in in the message
426 * NOTE - you cannot use this function AND the FindAdapters function at the
427 * same time, the application must use only one of them to get the adapters
428 */
429static void subsys_create_adapter(struct hpi_message *phm,
430 struct hpi_response *phr)
431{
432 /* create temp adapter obj, because we don't know what index yet */
433 struct hpi_adapter_obj ao;
434 struct hpi_adapter_obj *pao;
435 u32 os_error_code;
436 short error = 0;
437 u32 dsp_index = 0;
438
439 HPI_DEBUG_LOG(VERBOSE, "subsys_create_adapter\n");
440
441 memset(&ao, 0, sizeof(ao));
442
443 /* this HPI only creates adapters for TI/PCI2040 based devices */
444 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
445 return;
446 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
447 return;
448 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_PCI2040)
449 return;
450
451 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
452 if (!ao.priv) {
453 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
454 phr->error = HPI_ERROR_MEMORY_ALLOC;
455 return;
456 }
457
458 /* create the adapter object based on the resource information */
459 /*? memcpy(&ao.Pci,&phm->u.s.Resource.r.Pci,sizeof(ao.Pci)); */
460 ao.pci = *phm->u.s.resource.r.pci;
461
462 error = create_adapter_obj(&ao, &os_error_code);
463 if (!error)
464 error = hpi_add_adapter(&ao);
465 if (error) {
466 phr->u.s.data = os_error_code;
467 kfree(ao.priv);
468 phr->error = error;
469 return;
470 }
471 /* need to update paParentAdapter */
472 pao = hpi_find_adapter(ao.index);
473 if (!pao) {
474 /* We just added this adapter, why can't we find it!? */
475 HPI_DEBUG_LOG(ERROR, "lost adapter after boot\n");
476 phr->error = 950;
477 return;
478 }
479
480 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
481 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
482 phw->ado[dsp_index].pa_parent_adapter = pao;
483 }
484
485 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
486 phr->u.s.adapter_index = ao.index;
487 phr->u.s.num_adapters++;
488 phr->error = 0;
489}
490
491static void subsys_delete_adapter(struct hpi_message *phm,
492 struct hpi_response *phr)
493{
494 struct hpi_adapter_obj *pao = NULL;
495 struct hpi_hw_obj *phw;
496
497 pao = hpi_find_adapter(phm->adapter_index);
498 if (!pao)
499 return;
500
501 phw = (struct hpi_hw_obj *)pao->priv;
502
503 if (pao->has_control_cache)
504 hpi_free_control_cache(phw->p_cache);
505
506 hpi_delete_adapter(pao);
507 kfree(phw);
508
509 phr->error = 0;
510}
511
512/* this routine is called from SubSysFindAdapter and SubSysCreateAdapter */
513static short create_adapter_obj(struct hpi_adapter_obj *pao,
514 u32 *pos_error_code)
515{
516 short boot_error = 0;
517 u32 dsp_index = 0;
518 u32 control_cache_size = 0;
519 u32 control_cache_count = 0;
520 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
521
522 /* init error reporting */
523 pao->dsp_crashed = 0;
524
525 /* The PCI2040 has the following address map */
526 /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */
527 /* BAR1 - 32K = HPI registers on DSP */
528 phw->dw2040_HPICSR = pao->pci.ap_mem_base[0];
529 phw->dw2040_HPIDSP = pao->pci.ap_mem_base[1];
530 HPI_DEBUG_LOG(VERBOSE, "csr %p, dsp %p\n", phw->dw2040_HPICSR,
531 phw->dw2040_HPIDSP);
532
533 /* set addresses for the possible DSP HPI interfaces */
534 for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) {
535 phw->ado[dsp_index].prHPI_control =
536 phw->dw2040_HPIDSP + (CONTROL +
537 DSP_SPACING * dsp_index);
538
539 phw->ado[dsp_index].prHPI_address =
540 phw->dw2040_HPIDSP + (ADDRESS +
541 DSP_SPACING * dsp_index);
542 phw->ado[dsp_index].prHPI_data =
543 phw->dw2040_HPIDSP + (DATA + DSP_SPACING * dsp_index);
544
545 phw->ado[dsp_index].prHPI_data_auto_inc =
546 phw->dw2040_HPIDSP + (DATA_AUTOINC +
547 DSP_SPACING * dsp_index);
548
549 HPI_DEBUG_LOG(VERBOSE, "ctl %p, adr %p, dat %p, dat++ %p\n",
550 phw->ado[dsp_index].prHPI_control,
551 phw->ado[dsp_index].prHPI_address,
552 phw->ado[dsp_index].prHPI_data,
553 phw->ado[dsp_index].prHPI_data_auto_inc);
554
555 phw->ado[dsp_index].pa_parent_adapter = pao;
556 }
557
558 phw->pCI2040HPI_error_count = 0;
559 pao->has_control_cache = 0;
560
561 /* Set the default number of DSPs on this card */
562 /* This is (conditionally) adjusted after bootloading */
563 /* of the first DSP in the bootload section. */
564 phw->num_dsp = 1;
565
566 boot_error = hpi6000_adapter_boot_load_dsp(pao, pos_error_code);
567 if (boot_error)
568 return boot_error;
569
570 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
571
572 phw->message_buffer_address_on_dsp = 0L;
573 phw->response_buffer_address_on_dsp = 0L;
574
575 /* get info about the adapter by asking the adapter */
576 /* send a HPI_ADAPTER_GET_INFO message */
577 {
578 struct hpi_message hM;
579 struct hpi_response hR0; /* response from DSP 0 */
580 struct hpi_response hR1; /* response from DSP 1 */
581 u16 error = 0;
582
583 HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
584 memset(&hM, 0, sizeof(hM));
585 hM.type = HPI_TYPE_MESSAGE;
586 hM.size = sizeof(struct hpi_message);
587 hM.object = HPI_OBJ_ADAPTER;
588 hM.function = HPI_ADAPTER_GET_INFO;
589 hM.adapter_index = 0;
590 memset(&hR0, 0, sizeof(hR0));
591 memset(&hR1, 0, sizeof(hR1));
592 hR0.size = sizeof(hR0);
593 hR1.size = sizeof(hR1);
594
595 error = hpi6000_message_response_sequence(pao, 0, &hM, &hR0);
596 if (hR0.error) {
597 HPI_DEBUG_LOG(DEBUG, "message error %d\n", hR0.error);
598 return hR0.error;
599 }
600 if (phw->num_dsp == 2) {
601 error = hpi6000_message_response_sequence(pao, 1, &hM,
602 &hR1);
603 if (error)
604 return error;
605 }
606 pao->adapter_type = hR0.u.a.adapter_type;
607 pao->index = hR0.u.a.adapter_index;
608 }
609
610 memset(&phw->control_cache[0], 0,
611 sizeof(struct hpi_control_cache_single) *
612 HPI_NMIXER_CONTROLS);
613 /* Read the control cache length to figure out if it is turned on */
614 control_cache_size =
615 hpi_read_word(&phw->ado[0],
616 HPI_HIF_ADDR(control_cache_size_in_bytes));
617 if (control_cache_size) {
618 control_cache_count =
619 hpi_read_word(&phw->ado[0],
620 HPI_HIF_ADDR(control_cache_count));
621 pao->has_control_cache = 1;
622
623 phw->p_cache =
624 hpi_alloc_control_cache(control_cache_count,
625 control_cache_size, (struct hpi_control_cache_info *)
626 &phw->control_cache[0]
627 );
628 } else
629 pao->has_control_cache = 0;
630
631 HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n",
632 pao->adapter_type, pao->index);
633 pao->open = 0; /* upon creation the adapter is closed */
634 return 0;
635}
636
637/************************************************************************/
638/* ADAPTER */
639
640static void adapter_get_asserts(struct hpi_adapter_obj *pao,
641 struct hpi_message *phm, struct hpi_response *phr)
642{
643#ifndef HIDE_PCI_ASSERTS
644 /* if we have PCI2040 asserts then collect them */
645 if ((gw_pci_read_asserts > 0) || (gw_pci_write_asserts > 0)) {
646 phr->u.a.serial_number =
647 gw_pci_read_asserts * 100 + gw_pci_write_asserts;
648 phr->u.a.adapter_index = 1; /* assert count */
649 phr->u.a.adapter_type = -1; /* "dsp index" */
650 strcpy(phr->u.a.sz_adapter_assert, "PCI2040 error");
651 gw_pci_read_asserts = 0;
652 gw_pci_write_asserts = 0;
653 phr->error = 0;
654 } else
655#endif
656 hw_message(pao, phm, phr); /*get DSP asserts */
657
658 return;
659}
660
661/************************************************************************/
662/* LOW-LEVEL */
663
664static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
665 u32 *pos_error_code)
666{
667 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
668 short error;
669 u32 timeout;
670 u32 read = 0;
671 u32 i = 0;
672 u32 data = 0;
673 u32 j = 0;
674 u32 test_addr = 0x80000000;
675 u32 test_data = 0x00000001;
676 u32 dw2040_reset = 0;
677 u32 dsp_index = 0;
678 u32 endian = 0;
679 u32 adapter_info = 0;
680 u32 delay = 0;
681
682 struct dsp_code dsp_code;
683 u16 boot_load_family = 0;
684
685 /* NOTE don't use wAdapterType in this routine. It is not setup yet */
686
687 switch (pao->pci.subsys_device_id) {
688 case 0x5100:
689 case 0x5110: /* ASI5100 revB or higher with C6711D */
690 case 0x6100:
691 case 0x6200:
692 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
693 break;
694 case 0x8800:
695 boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x8800);
696 break;
697 default:
698 return HPI6000_ERROR_UNHANDLED_SUBSYS_ID;
699 }
700
701 /* reset all DSPs, indicate two DSPs are present
702 * set RST3-=1 to disconnect HAD8 to set DSP in little endian mode
703 */
704 endian = 0;
705 dw2040_reset = 0x0003000F;
706 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
707
708 /* read back register to make sure PCI2040 chip is functioning
709 * note that bits 4..15 are read-only and so should always return zero,
710 * even though we wrote 1 to them
711 */
712 for (i = 0; i < 1000; i++)
713 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
714 if (delay != dw2040_reset) {
715 HPI_DEBUG_LOG(ERROR, "INIT_PCI2040 %x %x\n", dw2040_reset,
716 delay);
717 return HPI6000_ERROR_INIT_PCI2040;
718 }
719
720 /* Indicate that DSP#0,1 is a C6X */
721 iowrite32(0x00000003, phw->dw2040_HPICSR + HPI_DATA_WIDTH);
722 /* set Bit30 and 29 - which will prevent Target aborts from being
723 * issued upon HPI or GP error
724 */
725 iowrite32(0x60000000, phw->dw2040_HPICSR + INTERRUPT_MASK_SET);
726
727 /* isolate DSP HAD8 line from PCI2040 so that
728 * Little endian can be set by pullup
729 */
730 dw2040_reset = dw2040_reset & (~(endian << 3));
731 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
732
733 phw->ado[0].c_dsp_rev = 'B'; /* revB */
734 phw->ado[1].c_dsp_rev = 'B'; /* revB */
735
736 /*Take both DSPs out of reset, setting HAD8 to the correct Endian */
737 dw2040_reset = dw2040_reset & (~0x00000001); /* start DSP 0 */
738 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
739 dw2040_reset = dw2040_reset & (~0x00000002); /* start DSP 1 */
740 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
741
742 /* set HAD8 back to PCI2040, now that DSP set to little endian mode */
743 dw2040_reset = dw2040_reset & (~0x00000008);
744 iowrite32(dw2040_reset, phw->dw2040_HPICSR + HPI_RESET);
745 /*delay to allow DSP to get going */
746 for (i = 0; i < 100; i++)
747 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
748
749 /* loop through all DSPs, downloading DSP code */
750 for (dsp_index = 0; dsp_index < phw->num_dsp; dsp_index++) {
751 struct dsp_obj *pdo = &phw->ado[dsp_index];
752
753 /* configure DSP so that we download code into the SRAM */
754 /* set control reg for little endian, HWOB=1 */
755 iowrite32(0x00010001, pdo->prHPI_control);
756
757 /* test access to the HPI address register (HPIA) */
758 test_data = 0x00000001;
759 for (j = 0; j < 32; j++) {
760 iowrite32(test_data, pdo->prHPI_address);
761 data = ioread32(pdo->prHPI_address);
762 if (data != test_data) {
763 HPI_DEBUG_LOG(ERROR, "INIT_DSPHPI %x %x %x\n",
764 test_data, data, dsp_index);
765 return HPI6000_ERROR_INIT_DSPHPI;
766 }
767 test_data = test_data << 1;
768 }
769
770/* if C6713 the setup PLL to generate 225MHz from 25MHz.
771* Since the PLLDIV1 read is sometimes wrong, even on a C6713,
772* we're going to do this unconditionally
773*/
774/* PLLDIV1 should have a value of 8000 after reset */
775/*
776 if (HpiReadWord(pdo,0x01B7C118) == 0x8000)
777*/
778 {
779 /* C6713 datasheet says we cannot program PLL from HPI,
780 * and indeed if we try to set the PLL multiply from the
781 * HPI, the PLL does not seem to lock,
782 * so we enable the PLL and use the default of x 7
783 */
784 /* bypass PLL */
785 hpi_write_word(pdo, 0x01B7C100, 0x0000);
786 for (i = 0; i < 100; i++)
787 delay = ioread32(phw->dw2040_HPICSR +
788 HPI_RESET);
789
790 /* ** use default of PLL x7 ** */
791 /* EMIF = 225/3=75MHz */
792 hpi_write_word(pdo, 0x01B7C120, 0x8002);
793 /* peri = 225/2 */
794 hpi_write_word(pdo, 0x01B7C11C, 0x8001);
795 /* cpu = 225/1 */
796 hpi_write_word(pdo, 0x01B7C118, 0x8000);
797 /* ~200us delay */
798 for (i = 0; i < 2000; i++)
799 delay = ioread32(phw->dw2040_HPICSR +
800 HPI_RESET);
801 /* PLL not bypassed */
802 hpi_write_word(pdo, 0x01B7C100, 0x0001);
803 /* ~200us delay */
804 for (i = 0; i < 2000; i++)
805 delay = ioread32(phw->dw2040_HPICSR +
806 HPI_RESET);
807 }
808
809 /* test r/w to internal DSP memory
810 * C6711 has L2 cache mapped to 0x0 when reset
811 *
812 * revB - because of bug 3.0.1 last HPI read
813 * (before HPI address issued) must be non-autoinc
814 */
815 /* test each bit in the 32bit word */
816 for (i = 0; i < 100; i++) {
817 test_addr = 0x00000000;
818 test_data = 0x00000001;
819 for (j = 0; j < 32; j++) {
820 hpi_write_word(pdo, test_addr + i, test_data);
821 data = hpi_read_word(pdo, test_addr + i);
822 if (data != test_data) {
823 HPI_DEBUG_LOG(ERROR,
824 "DSP mem %x %x %x %x\n",
825 test_addr + i, test_data,
826 data, dsp_index);
827
828 return HPI6000_ERROR_INIT_DSPINTMEM;
829 }
830 test_data = test_data << 1;
831 }
832 }
833
834 /* memory map of ASI6200
835 00000000-0000FFFF 16Kx32 internal program
836 01800000-019FFFFF Internal peripheral
837 80000000-807FFFFF CE0 2Mx32 SDRAM running @ 100MHz
838 90000000-9000FFFF CE1 Async peripherals:
839
840 EMIF config
841 ------------
842 Global EMIF control
843 0 -
844 1 -
845 2 -
846 3 CLK2EN = 1 CLKOUT2 enabled
847 4 CLK1EN = 0 CLKOUT1 disabled
848 5 EKEN = 1 <--!! C6713 specific, enables ECLKOUT
849 6 -
850 7 NOHOLD = 1 external HOLD disabled
851 8 HOLDA = 0 HOLDA output is low
852 9 HOLD = 0 HOLD input is low
853 10 ARDY = 1 ARDY input is high
854 11 BUSREQ = 0 BUSREQ output is low
855 12,13 Reserved = 1
856 */
857 hpi_write_word(pdo, 0x01800000, 0x34A8);
858
859 /* EMIF CE0 setup - 2Mx32 Sync DRAM
860 31..28 Wr setup
861 27..22 Wr strobe
862 21..20 Wr hold
863 19..16 Rd setup
864 15..14 -
865 13..8 Rd strobe
866 7..4 MTYPE 0011 Sync DRAM 32bits
867 3 Wr hold MSB
868 2..0 Rd hold
869 */
870 hpi_write_word(pdo, 0x01800008, 0x00000030);
871
872 /* EMIF SDRAM Extension
873 31-21 0
874 20 WR2RD = 0
875 19-18 WR2DEAC = 1
876 17 WR2WR = 0
877 16-15 R2WDQM = 2
878 14-12 RD2WR = 4
879 11-10 RD2DEAC = 1
880 9 RD2RD = 1
881 8-7 THZP = 10b
882 6-5 TWR = 2-1 = 01b (tWR = 10ns)
883 4 TRRD = 0b = 2 ECLK (tRRD = 14ns)
884 3-1 TRAS = 5-1 = 100b (Tras=42ns = 5 ECLK)
885 1 CAS latency = 3 ECLK
886 (for Micron 2M32-7 operating at 100Mhz)
887 */
888
889 /* need to use this else DSP code crashes */
890 hpi_write_word(pdo, 0x01800020, 0x001BDF29);
891
892 /* EMIF SDRAM control - set up for a 2Mx32 SDRAM (512x32x4 bank)
893 31 - -
894 30 SDBSZ 1 4 bank
895 29..28 SDRSZ 00 11 row address pins
896 27..26 SDCSZ 01 8 column address pins
897 25 RFEN 1 refersh enabled
898 24 INIT 1 init SDRAM
899 23..20 TRCD 0001
900 19..16 TRP 0001
901 15..12 TRC 0110
902 11..0 - -
903 */
904 /* need to use this else DSP code crashes */
905 hpi_write_word(pdo, 0x01800018, 0x47117000);
906
907 /* EMIF SDRAM Refresh Timing */
908 hpi_write_word(pdo, 0x0180001C, 0x00000410);
909
910 /*MIF CE1 setup - Async peripherals
911 @100MHz bus speed, each cycle is 10ns,
912 31..28 Wr setup = 1
913 27..22 Wr strobe = 3 30ns
914 21..20 Wr hold = 1
915 19..16 Rd setup =1
916 15..14 Ta = 2
917 13..8 Rd strobe = 3 30ns
918 7..4 MTYPE 0010 Async 32bits
919 3 Wr hold MSB =0
920 2..0 Rd hold = 1
921 */
922 {
923 u32 cE1 =
924 (1L << 28) | (3L << 22) | (1L << 20) | (1L <<
925 16) | (2L << 14) | (3L << 8) | (2L << 4) | 1L;
926 hpi_write_word(pdo, 0x01800004, cE1);
927 }
928
929 /* delay a little to allow SDRAM and DSP to "get going" */
930
931 for (i = 0; i < 1000; i++)
932 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
933
934 /* test access to SDRAM */
935 {
936 test_addr = 0x80000000;
937 test_data = 0x00000001;
938 /* test each bit in the 32bit word */
939 for (j = 0; j < 32; j++) {
940 hpi_write_word(pdo, test_addr, test_data);
941 data = hpi_read_word(pdo, test_addr);
942 if (data != test_data) {
943 HPI_DEBUG_LOG(ERROR,
944 "DSP dram %x %x %x %x\n",
945 test_addr, test_data, data,
946 dsp_index);
947
948 return HPI6000_ERROR_INIT_SDRAM1;
949 }
950 test_data = test_data << 1;
951 }
952 /* test every Nth address in the DRAM */
953#define DRAM_SIZE_WORDS 0x200000 /*2_mx32 */
954#define DRAM_INC 1024
955 test_addr = 0x80000000;
956 test_data = 0x0;
957 for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
958 hpi_write_word(pdo, test_addr + i, test_data);
959 test_data++;
960 }
961 test_addr = 0x80000000;
962 test_data = 0x0;
963 for (i = 0; i < DRAM_SIZE_WORDS; i = i + DRAM_INC) {
964 data = hpi_read_word(pdo, test_addr + i);
965 if (data != test_data) {
966 HPI_DEBUG_LOG(ERROR,
967 "DSP dram %x %x %x %x\n",
968 test_addr + i, test_data,
969 data, dsp_index);
970 return HPI6000_ERROR_INIT_SDRAM2;
971 }
972 test_data++;
973 }
974
975 }
976
977 /* write the DSP code down into the DSPs memory */
978 /*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
979 dsp_code.ps_dev = pao->pci.p_os_data;
980
981 error = hpi_dsp_code_open(boot_load_family, &dsp_code,
982 pos_error_code);
983
984 if (error)
985 return error;
986
987 while (1) {
988 u32 length;
989 u32 address;
990 u32 type;
991 u32 *pcode;
992
993 error = hpi_dsp_code_read_word(&dsp_code, &length);
994 if (error)
995 break;
996 if (length == 0xFFFFFFFF)
997 break; /* end of code */
998
999 error = hpi_dsp_code_read_word(&dsp_code, &address);
1000 if (error)
1001 break;
1002 error = hpi_dsp_code_read_word(&dsp_code, &type);
1003 if (error)
1004 break;
1005 error = hpi_dsp_code_read_block(length, &dsp_code,
1006 &pcode);
1007 if (error)
1008 break;
1009 error = hpi6000_dsp_block_write32(pao, (u16)dsp_index,
1010 address, pcode, length);
1011 if (error)
1012 break;
1013 }
1014
1015 if (error) {
1016 hpi_dsp_code_close(&dsp_code);
1017 return error;
1018 }
1019 /* verify that code was written correctly */
1020 /* this time through, assume no errors in DSP code file/array */
1021 hpi_dsp_code_rewind(&dsp_code);
1022 while (1) {
1023 u32 length;
1024 u32 address;
1025 u32 type;
1026 u32 *pcode;
1027
1028 hpi_dsp_code_read_word(&dsp_code, &length);
1029 if (length == 0xFFFFFFFF)
1030 break; /* end of code */
1031
1032 hpi_dsp_code_read_word(&dsp_code, &address);
1033 hpi_dsp_code_read_word(&dsp_code, &type);
1034 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1035
1036 for (i = 0; i < length; i++) {
1037 data = hpi_read_word(pdo, address);
1038 if (data != *pcode) {
1039 error = HPI6000_ERROR_INIT_VERIFY;
1040 HPI_DEBUG_LOG(ERROR,
1041 "DSP verify %x %x %x %x\n",
1042 address, *pcode, data,
1043 dsp_index);
1044 break;
1045 }
1046 pcode++;
1047 address += 4;
1048 }
1049 if (error)
1050 break;
1051 }
1052 hpi_dsp_code_close(&dsp_code);
1053 if (error)
1054 return error;
1055
1056 /* zero out the hostmailbox */
1057 {
1058 u32 address = HPI_HIF_ADDR(host_cmd);
1059 for (i = 0; i < 4; i++) {
1060 hpi_write_word(pdo, address, 0);
1061 address += 4;
1062 }
1063 }
1064 /* write the DSP number into the hostmailbox */
1065 /* structure before starting the DSP */
1066 hpi_write_word(pdo, HPI_HIF_ADDR(dsp_number), dsp_index);
1067
1068 /* write the DSP adapter Info into the */
1069 /* hostmailbox before starting the DSP */
1070 if (dsp_index > 0)
1071 hpi_write_word(pdo, HPI_HIF_ADDR(adapter_info),
1072 adapter_info);
1073
1074 /* step 3. Start code by sending interrupt */
1075 iowrite32(0x00030003, pdo->prHPI_control);
1076 for (i = 0; i < 10000; i++)
1077 delay = ioread32(phw->dw2040_HPICSR + HPI_RESET);
1078
1079 /* wait for a non-zero value in hostcmd -
1080 * indicating initialization is complete
1081 *
1082 * Init could take a while if DSP checks SDRAM memory
1083 * Was 200000. Increased to 2000000 for ASI8801 so we
1084 * don't get 938 errors.
1085 */
1086 timeout = 2000000;
1087 while (timeout) {
1088 do {
1089 read = hpi_read_word(pdo,
1090 HPI_HIF_ADDR(host_cmd));
1091 } while (--timeout
1092 && hpi6000_check_PCI2040_error_flag(pao,
1093 H6READ));
1094
1095 if (read)
1096 break;
1097 /* The following is a workaround for bug #94:
1098 * Bluescreen on install and subsequent boots on a
1099 * DELL PowerEdge 600SC PC with 1.8GHz P4 and
1100 * ServerWorks chipset. Without this delay the system
1101 * locks up with a bluescreen (NOT GPF or pagefault).
1102 */
1103 else
1104 hpios_delay_micro_seconds(1000);
1105 }
1106 if (timeout == 0)
1107 return HPI6000_ERROR_INIT_NOACK;
1108
1109 /* read the DSP adapter Info from the */
1110 /* hostmailbox structure after starting the DSP */
1111 if (dsp_index == 0) {
1112 /*u32 dwTestData=0; */
1113 u32 mask = 0;
1114
1115 adapter_info =
1116 hpi_read_word(pdo,
1117 HPI_HIF_ADDR(adapter_info));
1118 if (HPI_ADAPTER_FAMILY_ASI
1119 (HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER
1120 (adapter_info)) ==
1121 HPI_ADAPTER_FAMILY_ASI(0x6200))
1122 /* all 6200 cards have this many DSPs */
1123 phw->num_dsp = 2;
1124
1125 /* test that the PLD is programmed */
1126 /* and we can read/write 24bits */
1127#define PLD_BASE_ADDRESS 0x90000000L /*for ASI6100/6200/8800 */
1128
1129 switch (boot_load_family) {
1130 case HPI_ADAPTER_FAMILY_ASI(0x6200):
1131 /* ASI6100/6200 has 24bit path to FPGA */
1132 mask = 0xFFFFFF00L;
1133 /* ASI5100 uses AX6 code, */
1134 /* but has no PLD r/w register to test */
1135 if (HPI_ADAPTER_FAMILY_ASI(pao->pci.
1136 subsys_device_id) ==
1137 HPI_ADAPTER_FAMILY_ASI(0x5100))
1138 mask = 0x00000000L;
1139 break;
1140 case HPI_ADAPTER_FAMILY_ASI(0x8800):
1141 /* ASI8800 has 16bit path to FPGA */
1142 mask = 0xFFFF0000L;
1143 break;
1144 }
1145 test_data = 0xAAAAAA00L & mask;
1146 /* write to 24 bit Debug register (D31-D8) */
1147 hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
1148 read = hpi_read_word(pdo,
1149 PLD_BASE_ADDRESS + 4L) & mask;
1150 if (read != test_data) {
1151 HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
1152 read);
1153 return HPI6000_ERROR_INIT_PLDTEST1;
1154 }
1155 test_data = 0x55555500L & mask;
1156 hpi_write_word(pdo, PLD_BASE_ADDRESS + 4L, test_data);
1157 read = hpi_read_word(pdo,
1158 PLD_BASE_ADDRESS + 4L) & mask;
1159 if (read != test_data) {
1160 HPI_DEBUG_LOG(ERROR, "PLD %x %x\n", test_data,
1161 read);
1162 return HPI6000_ERROR_INIT_PLDTEST2;
1163 }
1164 }
1165 } /* for numDSP */
1166 return 0;
1167}
1168
1169#define PCI_TIMEOUT 100
1170
1171static int hpi_set_address(struct dsp_obj *pdo, u32 address)
1172{
1173 u32 timeout = PCI_TIMEOUT;
1174
1175 do {
1176 iowrite32(address, pdo->prHPI_address);
1177 } while (hpi6000_check_PCI2040_error_flag(pdo->pa_parent_adapter,
1178 H6WRITE)
1179 && --timeout);
1180
1181 if (timeout)
1182 return 0;
1183
1184 return 1;
1185}
1186
1187/* write one word to the HPI port */
1188static void hpi_write_word(struct dsp_obj *pdo, u32 address, u32 data)
1189{
1190 if (hpi_set_address(pdo, address))
1191 return;
1192 iowrite32(data, pdo->prHPI_data);
1193}
1194
1195/* read one word from the HPI port */
1196static u32 hpi_read_word(struct dsp_obj *pdo, u32 address)
1197{
1198 u32 data = 0;
1199
1200 if (hpi_set_address(pdo, address))
1201 return 0; /*? no way to return error */
1202
1203 /* take care of errata in revB DSP (2.0.1) */
1204 data = ioread32(pdo->prHPI_data);
1205 return data;
1206}
1207
1208/* write a block of 32bit words to the DSP HPI port using auto-inc mode */
1209static void hpi_write_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1210 u32 length)
1211{
1212 u16 length16 = length - 1;
1213
1214 if (length == 0)
1215 return;
1216
1217 if (hpi_set_address(pdo, address))
1218 return;
1219
1220 iowrite32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
1221
1222 /* take care of errata in revB DSP (2.0.1) */
1223 /* must end with non auto-inc */
1224 iowrite32(*(pdata + length - 1), pdo->prHPI_data);
1225}
1226
1227/** read a block of 32bit words from the DSP HPI port using auto-inc mode
1228 */
1229static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata,
1230 u32 length)
1231{
1232 u16 length16 = length - 1;
1233
1234 if (length == 0)
1235 return;
1236
1237 if (hpi_set_address(pdo, address))
1238 return;
1239
1240 ioread32_rep(pdo->prHPI_data_auto_inc, pdata, length16);
1241
1242 /* take care of errata in revB DSP (2.0.1) */
1243 /* must end with non auto-inc */
1244 *(pdata + length - 1) = ioread32(pdo->prHPI_data);
1245}
1246
1247static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao,
1248 u16 dsp_index, u32 hpi_address, u32 *source, u32 count)
1249{
1250 struct dsp_obj *pdo =
1251 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1252 u32 time_out = PCI_TIMEOUT;
1253 int c6711_burst_size = 128;
1254 u32 local_hpi_address = hpi_address;
1255 int local_count = count;
1256 int xfer_size;
1257 u32 *pdata = source;
1258
1259 while (local_count) {
1260 if (local_count > c6711_burst_size)
1261 xfer_size = c6711_burst_size;
1262 else
1263 xfer_size = local_count;
1264
1265 time_out = PCI_TIMEOUT;
1266 do {
1267 hpi_write_block(pdo, local_hpi_address, pdata,
1268 xfer_size);
1269 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1270 && --time_out);
1271
1272 if (!time_out)
1273 break;
1274 pdata += xfer_size;
1275 local_hpi_address += sizeof(u32) * xfer_size;
1276 local_count -= xfer_size;
1277 }
1278
1279 if (time_out)
1280 return 0;
1281 else
1282 return 1;
1283}
1284
1285static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao,
1286 u16 dsp_index, u32 hpi_address, u32 *dest, u32 count)
1287{
1288 struct dsp_obj *pdo =
1289 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1290 u32 time_out = PCI_TIMEOUT;
1291 int c6711_burst_size = 16;
1292 u32 local_hpi_address = hpi_address;
1293 int local_count = count;
1294 int xfer_size;
1295 u32 *pdata = dest;
1296 u32 loop_count = 0;
1297
1298 while (local_count) {
1299 if (local_count > c6711_burst_size)
1300 xfer_size = c6711_burst_size;
1301 else
1302 xfer_size = local_count;
1303
1304 time_out = PCI_TIMEOUT;
1305 do {
1306 hpi_read_block(pdo, local_hpi_address, pdata,
1307 xfer_size);
1308 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1309 && --time_out);
1310 if (!time_out)
1311 break;
1312
1313 pdata += xfer_size;
1314 local_hpi_address += sizeof(u32) * xfer_size;
1315 local_count -= xfer_size;
1316 loop_count++;
1317 }
1318
1319 if (time_out)
1320 return 0;
1321 else
1322 return 1;
1323}
1324
1325static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao,
1326 u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr)
1327{
1328 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1329 struct dsp_obj *pdo = &phw->ado[dsp_index];
1330 u32 timeout;
1331 u16 ack;
1332 u32 address;
1333 u32 length;
1334 u32 *p_data;
1335 u16 error = 0;
1336
1337 /* does the DSP we are referencing exist? */
1338 if (dsp_index >= phw->num_dsp)
1339 return HPI6000_ERROR_MSG_INVALID_DSP_INDEX;
1340
1341 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1342 if (ack & HPI_HIF_ERROR_MASK) {
1343 pao->dsp_crashed++;
1344 return HPI6000_ERROR_MSG_RESP_IDLE_TIMEOUT;
1345 }
1346 pao->dsp_crashed = 0;
1347
1348 /* send the message */
1349
1350 /* get the address and size */
1351 if (phw->message_buffer_address_on_dsp == 0) {
1352 timeout = TIMEOUT;
1353 do {
1354 address =
1355 hpi_read_word(pdo,
1356 HPI_HIF_ADDR(message_buffer_address));
1357 phw->message_buffer_address_on_dsp = address;
1358 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1359 && --timeout);
1360 if (!timeout)
1361 return HPI6000_ERROR_MSG_GET_ADR;
1362 } else
1363 address = phw->message_buffer_address_on_dsp;
1364
1365 /* dwLength = sizeof(struct hpi_message); */
1366 length = phm->size;
1367
1368 /* send it */
1369 p_data = (u32 *)phm;
1370 if (hpi6000_dsp_block_write32(pao, dsp_index, address, p_data,
1371 (u16)length / 4))
1372 return HPI6000_ERROR_MSG_RESP_BLOCKWRITE32;
1373
1374 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_GET_RESP))
1375 return HPI6000_ERROR_MSG_RESP_GETRESPCMD;
1376 hpi6000_send_dsp_interrupt(pdo);
1377
1378 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_RESP);
1379 if (ack & HPI_HIF_ERROR_MASK)
1380 return HPI6000_ERROR_MSG_RESP_GET_RESP_ACK;
1381
1382 /* get the address and size */
1383 if (phw->response_buffer_address_on_dsp == 0) {
1384 timeout = TIMEOUT;
1385 do {
1386 address =
1387 hpi_read_word(pdo,
1388 HPI_HIF_ADDR(response_buffer_address));
1389 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1390 && --timeout);
1391 phw->response_buffer_address_on_dsp = address;
1392
1393 if (!timeout)
1394 return HPI6000_ERROR_RESP_GET_ADR;
1395 } else
1396 address = phw->response_buffer_address_on_dsp;
1397
1398 /* read the length of the response back from the DSP */
1399 timeout = TIMEOUT;
1400 do {
1401 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1402 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1403 if (!timeout)
1404 length = sizeof(struct hpi_response);
1405
1406 /* get it */
1407 p_data = (u32 *)phr;
1408 if (hpi6000_dsp_block_read32(pao, dsp_index, address, p_data,
1409 (u16)length / 4))
1410 return HPI6000_ERROR_MSG_RESP_BLOCKREAD32;
1411
1412 /* set i/f back to idle */
1413 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1414 return HPI6000_ERROR_MSG_RESP_IDLECMD;
1415 hpi6000_send_dsp_interrupt(pdo);
1416
1417 error = hpi_validate_response(phm, phr);
1418 return error;
1419}
1420
1421/* have to set up the below defines to match stuff in the MAP file */
1422
1423#define MSG_ADDRESS (HPI_HIF_BASE+0x18)
1424#define MSG_LENGTH 11
1425#define RESP_ADDRESS (HPI_HIF_BASE+0x44)
1426#define RESP_LENGTH 16
1427#define QUEUE_START (HPI_HIF_BASE+0x88)
1428#define QUEUE_SIZE 0x8000
1429
1430static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords)
1431{
1432/*#define CHECKING // comment this line in to enable checking */
1433#ifdef CHECKING
1434 if (address < (u32)MSG_ADDRESS)
1435 return 0;
1436 if (address > (u32)(QUEUE_START + QUEUE_SIZE))
1437 return 0;
1438 if ((address + (length_in_dwords << 2)) >
1439 (u32)(QUEUE_START + QUEUE_SIZE))
1440 return 0;
1441#else
1442 (void)address;
1443 (void)length_in_dwords;
1444 return 1;
1445#endif
1446}
1447
1448static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1449 struct hpi_message *phm, struct hpi_response *phr)
1450{
1451 struct dsp_obj *pdo =
1452 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1453 u32 data_sent = 0;
1454 u16 ack;
1455 u32 length, address;
1456 u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1457 u16 time_out = 8;
1458
1459 (void)phr;
1460
1461 /* round dwDataSize down to nearest 4 bytes */
1462 while ((data_sent < (phm->u.d.u.data.data_size & ~3L))
1463 && --time_out) {
1464 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1465 if (ack & HPI_HIF_ERROR_MASK)
1466 return HPI6000_ERROR_SEND_DATA_IDLE_TIMEOUT;
1467
1468 if (hpi6000_send_host_command(pao, dsp_index,
1469 HPI_HIF_SEND_DATA))
1470 return HPI6000_ERROR_SEND_DATA_CMD;
1471
1472 hpi6000_send_dsp_interrupt(pdo);
1473
1474 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_SEND_DATA);
1475
1476 if (ack & HPI_HIF_ERROR_MASK)
1477 return HPI6000_ERROR_SEND_DATA_ACK;
1478
1479 do {
1480 /* get the address and size */
1481 address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1482 /* DSP returns number of DWORDS */
1483 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1484 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1485
1486 if (!hpi6000_send_data_check_adr(address, length))
1487 return HPI6000_ERROR_SEND_DATA_ADR;
1488
1489 /* send the data. break data into 512 DWORD blocks (2K bytes)
1490 * and send using block write. 2Kbytes is the max as this is the
1491 * memory window given to the HPI data register by the PCI2040
1492 */
1493
1494 {
1495 u32 len = length;
1496 u32 blk_len = 512;
1497 while (len) {
1498 if (len < blk_len)
1499 blk_len = len;
1500 if (hpi6000_dsp_block_write32(pao, dsp_index,
1501 address, p_data, blk_len))
1502 return HPI6000_ERROR_SEND_DATA_WRITE;
1503 address += blk_len * 4;
1504 p_data += blk_len;
1505 len -= blk_len;
1506 }
1507 }
1508
1509 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1510 return HPI6000_ERROR_SEND_DATA_IDLECMD;
1511
1512 hpi6000_send_dsp_interrupt(pdo);
1513
1514 data_sent += length * 4;
1515 }
1516 if (!time_out)
1517 return HPI6000_ERROR_SEND_DATA_TIMEOUT;
1518 return 0;
1519}
1520
1521static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index,
1522 struct hpi_message *phm, struct hpi_response *phr)
1523{
1524 struct dsp_obj *pdo =
1525 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1526 u32 data_got = 0;
1527 u16 ack;
1528 u32 length, address;
1529 u32 *p_data = (u32 *)phm->u.d.u.data.pb_data;
1530
1531 (void)phr; /* this parameter not used! */
1532
1533 /* round dwDataSize down to nearest 4 bytes */
1534 while (data_got < (phm->u.d.u.data.data_size & ~3L)) {
1535 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_IDLE);
1536 if (ack & HPI_HIF_ERROR_MASK)
1537 return HPI6000_ERROR_GET_DATA_IDLE_TIMEOUT;
1538
1539 if (hpi6000_send_host_command(pao, dsp_index,
1540 HPI_HIF_GET_DATA))
1541 return HPI6000_ERROR_GET_DATA_CMD;
1542 hpi6000_send_dsp_interrupt(pdo);
1543
1544 ack = hpi6000_wait_dsp_ack(pao, dsp_index, HPI_HIF_GET_DATA);
1545
1546 if (ack & HPI_HIF_ERROR_MASK)
1547 return HPI6000_ERROR_GET_DATA_ACK;
1548
1549 /* get the address and size */
1550 do {
1551 address = hpi_read_word(pdo, HPI_HIF_ADDR(address));
1552 length = hpi_read_word(pdo, HPI_HIF_ADDR(length));
1553 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ));
1554
1555 /* read the data */
1556 {
1557 u32 len = length;
1558 u32 blk_len = 512;
1559 while (len) {
1560 if (len < blk_len)
1561 blk_len = len;
1562 if (hpi6000_dsp_block_read32(pao, dsp_index,
1563 address, p_data, blk_len))
1564 return HPI6000_ERROR_GET_DATA_READ;
1565 address += blk_len * 4;
1566 p_data += blk_len;
1567 len -= blk_len;
1568 }
1569 }
1570
1571 if (hpi6000_send_host_command(pao, dsp_index, HPI_HIF_IDLE))
1572 return HPI6000_ERROR_GET_DATA_IDLECMD;
1573 hpi6000_send_dsp_interrupt(pdo);
1574
1575 data_got += length * 4;
1576 }
1577 return 0;
1578}
1579
1580static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo)
1581{
1582 iowrite32(0x00030003, pdo->prHPI_control); /* DSPINT */
1583}
1584
1585static short hpi6000_send_host_command(struct hpi_adapter_obj *pao,
1586 u16 dsp_index, u32 host_cmd)
1587{
1588 struct dsp_obj *pdo =
1589 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1590 u32 timeout = TIMEOUT;
1591
1592 /* set command */
1593 do {
1594 hpi_write_word(pdo, HPI_HIF_ADDR(host_cmd), host_cmd);
1595 /* flush the FIFO */
1596 hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1597 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE) && --timeout);
1598
1599 /* reset the interrupt bit */
1600 iowrite32(0x00040004, pdo->prHPI_control);
1601
1602 if (timeout)
1603 return 0;
1604 else
1605 return 1;
1606}
1607
1608/* if the PCI2040 has recorded an HPI timeout, reset the error and return 1 */
1609static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao,
1610 u16 read_or_write)
1611{
1612 u32 hPI_error;
1613
1614 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1615
1616 /* read the error bits from the PCI2040 */
1617 hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1618 if (hPI_error) {
1619 /* reset the error flag */
1620 iowrite32(0L, phw->dw2040_HPICSR + HPI_ERROR_REPORT);
1621 phw->pCI2040HPI_error_count++;
1622 if (read_or_write == 1)
1623 gw_pci_read_asserts++; /************* inc global */
1624 else
1625 gw_pci_write_asserts++;
1626 return 1;
1627 } else
1628 return 0;
1629}
1630
1631static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index,
1632 u32 ack_value)
1633{
1634 struct dsp_obj *pdo =
1635 &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index];
1636 u32 ack = 0L;
1637 u32 timeout;
1638 u32 hPIC = 0L;
1639
1640 /* wait for host interrupt to signal ack is ready */
1641 timeout = TIMEOUT;
1642 while (--timeout) {
1643 hPIC = ioread32(pdo->prHPI_control);
1644 if (hPIC & 0x04) /* 0x04 = HINT from DSP */
1645 break;
1646 }
1647 if (timeout == 0)
1648 return HPI_HIF_ERROR_MASK;
1649
1650 /* wait for dwAckValue */
1651 timeout = TIMEOUT;
1652 while (--timeout) {
1653 /* read the ack mailbox */
1654 ack = hpi_read_word(pdo, HPI_HIF_ADDR(dsp_ack));
1655 if (ack == ack_value)
1656 break;
1657 if ((ack & HPI_HIF_ERROR_MASK)
1658 && !hpi6000_check_PCI2040_error_flag(pao, H6READ))
1659 break;
1660 /*for (i=0;i<1000;i++) */
1661 /* dwPause=i+1; */
1662 }
1663 if (ack & HPI_HIF_ERROR_MASK)
1664 /* indicates bad read from DSP -
1665 typically 0xffffff is read for some reason */
1666 ack = HPI_HIF_ERROR_MASK;
1667
1668 if (timeout == 0)
1669 ack = HPI_HIF_ERROR_MASK;
1670 return (short)ack;
1671}
1672
1673static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao,
1674 struct hpi_message *phm)
1675{
1676 const u16 dsp_index = 0;
1677 struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
1678 struct dsp_obj *pdo = &phw->ado[dsp_index];
1679 u32 timeout;
1680 u32 cache_dirty_flag;
1681 u16 err;
1682
1683 hpios_dsplock_lock(pao);
1684
1685 timeout = TIMEOUT;
1686 do {
1687 cache_dirty_flag =
1688 hpi_read_word((struct dsp_obj *)pdo,
1689 HPI_HIF_ADDR(control_cache_is_dirty));
1690 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ) && --timeout);
1691 if (!timeout) {
1692 err = HPI6000_ERROR_CONTROL_CACHE_PARAMS;
1693 goto unlock;
1694 }
1695
1696 if (cache_dirty_flag) {
1697 /* read the cached controls */
1698 u32 address;
1699 u32 length;
1700
1701 timeout = TIMEOUT;
1702 if (pdo->control_cache_address_on_dsp == 0) {
1703 do {
1704 address =
1705 hpi_read_word((struct dsp_obj *)pdo,
1706 HPI_HIF_ADDR(control_cache_address));
1707
1708 length = hpi_read_word((struct dsp_obj *)pdo,
1709 HPI_HIF_ADDR
1710 (control_cache_size_in_bytes));
1711 } while (hpi6000_check_PCI2040_error_flag(pao, H6READ)
1712 && --timeout);
1713 if (!timeout) {
1714 err = HPI6000_ERROR_CONTROL_CACHE_ADDRLEN;
1715 goto unlock;
1716 }
1717 pdo->control_cache_address_on_dsp = address;
1718 pdo->control_cache_length_on_dsp = length;
1719 } else {
1720 address = pdo->control_cache_address_on_dsp;
1721 length = pdo->control_cache_length_on_dsp;
1722 }
1723
1724 if (hpi6000_dsp_block_read32(pao, dsp_index, address,
1725 (u32 *)&phw->control_cache[0],
1726 length / sizeof(u32))) {
1727 err = HPI6000_ERROR_CONTROL_CACHE_READ;
1728 goto unlock;
1729 }
1730 do {
1731 hpi_write_word((struct dsp_obj *)pdo,
1732 HPI_HIF_ADDR(control_cache_is_dirty), 0);
1733 /* flush the FIFO */
1734 hpi_set_address(pdo, HPI_HIF_ADDR(host_cmd));
1735 } while (hpi6000_check_PCI2040_error_flag(pao, H6WRITE)
1736 && --timeout);
1737 if (!timeout) {
1738 err = HPI6000_ERROR_CONTROL_CACHE_FLUSH;
1739 goto unlock;
1740 }
1741
1742 }
1743 err = 0;
1744
1745unlock:
1746 hpios_dsplock_unlock(pao);
1747 return err;
1748}
1749
1750/** Get dsp index for multi DSP adapters only */
1751static u16 get_dsp_index(struct hpi_adapter_obj *pao, struct hpi_message *phm)
1752{
1753 u16 ret = 0;
1754 switch (phm->object) {
1755 case HPI_OBJ_ISTREAM:
1756 if (phm->obj_index < 2)
1757 ret = 1;
1758 break;
1759 case HPI_OBJ_PROFILE:
1760 ret = phm->obj_index;
1761 break;
1762 default:
1763 break;
1764 }
1765 return ret;
1766}
1767
1768/** Complete transaction with DSP
1769
1770Send message, get response, send or get stream data if any.
1771*/
1772static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
1773 struct hpi_response *phr)
1774{
1775 u16 error = 0;
1776 u16 dsp_index = 0;
1777 u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp;
1778 hpios_dsplock_lock(pao);
1779
1780 if (num_dsp < 2)
1781 dsp_index = 0;
1782 else {
1783 dsp_index = get_dsp_index(pao, phm);
1784
1785 /* is this checked on the DSP anyway? */
1786 if ((phm->function == HPI_ISTREAM_GROUP_ADD)
1787 || (phm->function == HPI_OSTREAM_GROUP_ADD)) {
1788 struct hpi_message hm;
1789 u16 add_index;
1790 hm.obj_index = phm->u.d.u.stream.stream_index;
1791 hm.object = phm->u.d.u.stream.object_type;
1792 add_index = get_dsp_index(pao, &hm);
1793 if (add_index != dsp_index) {
1794 phr->error = HPI_ERROR_NO_INTERDSP_GROUPS;
1795 return;
1796 }
1797 }
1798 }
1799 error = hpi6000_message_response_sequence(pao, dsp_index, phm, phr);
1800
1801 /* maybe an error response */
1802 if (error) {
1803 /* something failed in the HPI/DSP interface */
1804 phr->error = error;
1805 /* just the header of the response is valid */
1806 phr->size = sizeof(struct hpi_response_header);
1807 goto err;
1808 }
1809
1810 if (phr->error != 0) /* something failed in the DSP */
1811 goto err;
1812
1813 switch (phm->function) {
1814 case HPI_OSTREAM_WRITE:
1815 case HPI_ISTREAM_ANC_WRITE:
1816 error = hpi6000_send_data(pao, dsp_index, phm, phr);
1817 break;
1818 case HPI_ISTREAM_READ:
1819 case HPI_OSTREAM_ANC_READ:
1820 error = hpi6000_get_data(pao, dsp_index, phm, phr);
1821 break;
1822 case HPI_ADAPTER_GET_ASSERT:
1823 phr->u.a.adapter_index = 0; /* dsp 0 default */
1824 if (num_dsp == 2) {
1825 if (!phr->u.a.adapter_type) {
1826 /* no assert from dsp 0, check dsp 1 */
1827 error = hpi6000_message_response_sequence(pao,
1828 1, phm, phr);
1829 phr->u.a.adapter_index = 1;
1830 }
1831 }
1832 }
1833
1834 if (error)
1835 phr->error = error;
1836
1837err:
1838 hpios_dsplock_unlock(pao);
1839 return;
1840}
diff --git a/sound/pci/asihpi/hpi6000.h b/sound/pci/asihpi/hpi6000.h
new file mode 100644
index 000000000000..4c7d507c0ecd
--- /dev/null
+++ b/sound/pci/asihpi/hpi6000.h
@@ -0,0 +1,70 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Public declarations for DSP Proramming Interface to TI C6701
20
21Shared between hpi6000.c and DSP code
22
23(C) Copyright AudioScience Inc. 1998-2003
24******************************************************************************/
25
26#ifndef _HPI6000_H_
27#define _HPI6000_H_
28
29#define HPI_NMIXER_CONTROLS 200
30
31/*
32 * Control caching is always supported in the HPI code.
33 * The DSP should make sure that dwControlCacheSizeInBytes is initialized to 0
34 * during boot to make it in-active.
35 */
36struct hpi_hif_6000 {
37 u32 host_cmd;
38 u32 dsp_ack;
39 u32 address;
40 u32 length;
41 u32 message_buffer_address;
42 u32 response_buffer_address;
43 u32 dsp_number;
44 u32 adapter_info;
45 u32 control_cache_is_dirty;
46 u32 control_cache_address;
47 u32 control_cache_size_in_bytes;
48 u32 control_cache_count;
49};
50
51#define HPI_HIF_PACK_ADAPTER_INFO(adapter, version_major, version_minor) \
52 ((adapter << 16) | (version_major << 8) | version_minor)
53#define HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER(adapterinfo) \
54 ((adapterinfo >> 16) & 0xffff)
55#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MAJOR(adapterinfo) \
56 ((adapterinfo >> 8) & 0xff)
57#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MINOR(adapterinfo) \
58 (adapterinfo & 0xff)
59
60/* Command/status exchanged between host and DSP */
61#define HPI_HIF_IDLE 0
62#define HPI_HIF_SEND_MSG 1
63#define HPI_HIF_GET_RESP 2
64#define HPI_HIF_DATA_MASK 0x10
65#define HPI_HIF_SEND_DATA 0x13
66#define HPI_HIF_GET_DATA 0x14
67#define HPI_HIF_SEND_DONE 5
68#define HPI_HIF_RESET 9
69
70#endif /* _HPI6000_H_ */
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c
new file mode 100644
index 000000000000..5e88c1fc2b9e
--- /dev/null
+++ b/sound/pci/asihpi/hpi6205.c
@@ -0,0 +1,2331 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) for AudioScience
20 ASI50xx, AS51xx, ASI6xxx, ASI87xx ASI89xx series adapters.
21 These PCI and PCIe bus adapters are based on a
22 TMS320C6205 PCI bus mastering DSP,
23 and (except ASI50xx) TI TMS320C6xxx floating point DSP
24
25 Exported function:
26 void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
27
28(C) Copyright AudioScience Inc. 1998-2010
29*******************************************************************************/
30#define SOURCEFILE_NAME "hpi6205.c"
31
32#include "hpi_internal.h"
33#include "hpimsginit.h"
34#include "hpidebug.h"
35#include "hpi6205.h"
36#include "hpidspcd.h"
37#include "hpicmn.h"
38
39/*****************************************************************************/
40/* HPI6205 specific error codes */
41#define HPI6205_ERROR_BASE 1000
42/*#define HPI6205_ERROR_MEM_ALLOC 1001 */
43#define HPI6205_ERROR_6205_NO_IRQ 1002
44#define HPI6205_ERROR_6205_INIT_FAILED 1003
45/*#define HPI6205_ERROR_MISSING_DSPCODE 1004 */
46#define HPI6205_ERROR_UNKNOWN_PCI_DEVICE 1005
47#define HPI6205_ERROR_6205_REG 1006
48#define HPI6205_ERROR_6205_DSPPAGE 1007
49#define HPI6205_ERROR_BAD_DSPINDEX 1008
50#define HPI6205_ERROR_C6713_HPIC 1009
51#define HPI6205_ERROR_C6713_HPIA 1010
52#define HPI6205_ERROR_C6713_PLL 1011
53#define HPI6205_ERROR_DSP_INTMEM 1012
54#define HPI6205_ERROR_DSP_EXTMEM 1013
55#define HPI6205_ERROR_DSP_PLD 1014
56#define HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT 1015
57#define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016
58#define HPI6205_ERROR_6205_EEPROM 1017
59#define HPI6205_ERROR_DSP_EMIF 1018
60
61#define hpi6205_error(dsp_index, err) (err)
62/*****************************************************************************/
63/* for C6205 PCI i/f */
64/* Host Status Register (HSR) bitfields */
65#define C6205_HSR_INTSRC 0x01
66#define C6205_HSR_INTAVAL 0x02
67#define C6205_HSR_INTAM 0x04
68#define C6205_HSR_CFGERR 0x08
69#define C6205_HSR_EEREAD 0x10
70/* Host-to-DSP Control Register (HDCR) bitfields */
71#define C6205_HDCR_WARMRESET 0x01
72#define C6205_HDCR_DSPINT 0x02
73#define C6205_HDCR_PCIBOOT 0x04
74/* DSP Page Register (DSPP) bitfields, */
75/* defines 4 Mbyte page that BAR0 points to */
76#define C6205_DSPP_MAP1 0x400
77
78/* BAR0 maps to prefetchable 4 Mbyte memory block set by DSPP.
79 * BAR1 maps to non-prefetchable 8 Mbyte memory block
80 * of DSP memory mapped registers (starting at 0x01800000).
81 * 0x01800000 is hardcoded in the PCI i/f, so that only the offset from this
82 * needs to be added to the BAR1 base address set in the PCI config reg
83 */
84#define C6205_BAR1_PCI_IO_OFFSET (0x027FFF0L)
85#define C6205_BAR1_HSR (C6205_BAR1_PCI_IO_OFFSET)
86#define C6205_BAR1_HDCR (C6205_BAR1_PCI_IO_OFFSET+4)
87#define C6205_BAR1_DSPP (C6205_BAR1_PCI_IO_OFFSET+8)
88
89/* used to control LED (revA) and reset C6713 (revB) */
90#define C6205_BAR0_TIMER1_CTL (0x01980000L)
91
92/* For first 6713 in CE1 space, using DA17,16,2 */
93#define HPICL_ADDR 0x01400000L
94#define HPICH_ADDR 0x01400004L
95#define HPIAL_ADDR 0x01410000L
96#define HPIAH_ADDR 0x01410004L
97#define HPIDIL_ADDR 0x01420000L
98#define HPIDIH_ADDR 0x01420004L
99#define HPIDL_ADDR 0x01430000L
100#define HPIDH_ADDR 0x01430004L
101
102#define C6713_EMIF_GCTL 0x01800000
103#define C6713_EMIF_CE1 0x01800004
104#define C6713_EMIF_CE0 0x01800008
105#define C6713_EMIF_CE2 0x01800010
106#define C6713_EMIF_CE3 0x01800014
107#define C6713_EMIF_SDRAMCTL 0x01800018
108#define C6713_EMIF_SDRAMTIMING 0x0180001C
109#define C6713_EMIF_SDRAMEXT 0x01800020
110
111struct hpi_hw_obj {
112 /* PCI registers */
113 __iomem u32 *prHSR;
114 __iomem u32 *prHDCR;
115 __iomem u32 *prDSPP;
116
117 u32 dsp_page;
118
119 struct consistent_dma_area h_locked_mem;
120 struct bus_master_interface *p_interface_buffer;
121
122 u16 flag_outstream_just_reset[HPI_MAX_STREAMS];
123 /* a non-NULL handle means there is an HPI allocated buffer */
124 struct consistent_dma_area instream_host_buffers[HPI_MAX_STREAMS];
125 struct consistent_dma_area outstream_host_buffers[HPI_MAX_STREAMS];
126 /* non-zero size means a buffer exists, may be external */
127 u32 instream_host_buffer_size[HPI_MAX_STREAMS];
128 u32 outstream_host_buffer_size[HPI_MAX_STREAMS];
129
130 struct consistent_dma_area h_control_cache;
131 struct consistent_dma_area h_async_event_buffer;
132/* struct hpi_control_cache_single *pControlCache; */
133 struct hpi_async_event *p_async_event_buffer;
134 struct hpi_control_cache *p_cache;
135};
136
137/*****************************************************************************/
138/* local prototypes */
139
140#define check_before_bbm_copy(status, p_bbm_data, l_first_write, l_second_write)
141
142static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us);
143
144static void send_dsp_command(struct hpi_hw_obj *phw, int cmd);
145
146static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
147 u32 *pos_error_code);
148
149static u16 message_response_sequence(struct hpi_adapter_obj *pao,
150 struct hpi_message *phm, struct hpi_response *phr);
151
152static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
153 struct hpi_response *phr);
154
155#define HPI6205_TIMEOUT 1000000
156
157static void subsys_create_adapter(struct hpi_message *phm,
158 struct hpi_response *phr);
159static void subsys_delete_adapter(struct hpi_message *phm,
160 struct hpi_response *phr);
161
162static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
163 u32 *pos_error_code);
164
165static void delete_adapter_obj(struct hpi_adapter_obj *pao);
166
167static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
168 struct hpi_message *phm, struct hpi_response *phr);
169
170static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
171 struct hpi_message *phm, struct hpi_response *phr);
172
173static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
174 struct hpi_message *phm, struct hpi_response *phr);
175static void outstream_write(struct hpi_adapter_obj *pao,
176 struct hpi_message *phm, struct hpi_response *phr);
177
178static void outstream_get_info(struct hpi_adapter_obj *pao,
179 struct hpi_message *phm, struct hpi_response *phr);
180
181static void outstream_start(struct hpi_adapter_obj *pao,
182 struct hpi_message *phm, struct hpi_response *phr);
183
184static void outstream_open(struct hpi_adapter_obj *pao,
185 struct hpi_message *phm, struct hpi_response *phr);
186
187static void outstream_reset(struct hpi_adapter_obj *pao,
188 struct hpi_message *phm, struct hpi_response *phr);
189
190static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
191 struct hpi_message *phm, struct hpi_response *phr);
192
193static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
194 struct hpi_message *phm, struct hpi_response *phr);
195
196static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
197 struct hpi_message *phm, struct hpi_response *phr);
198
199static void instream_read(struct hpi_adapter_obj *pao,
200 struct hpi_message *phm, struct hpi_response *phr);
201
202static void instream_get_info(struct hpi_adapter_obj *pao,
203 struct hpi_message *phm, struct hpi_response *phr);
204
205static void instream_start(struct hpi_adapter_obj *pao,
206 struct hpi_message *phm, struct hpi_response *phr);
207
208static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
209 u32 address);
210
211static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
212 u32 address, u32 data);
213
214static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao,
215 int dsp_index);
216
217static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
218 u32 address, u32 length);
219
220static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
221 int dsp_index);
222
223static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
224 int dsp_index);
225
226static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
227
228/*****************************************************************************/
229
230static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
231{
232
233 switch (phm->function) {
234 case HPI_SUBSYS_OPEN:
235 case HPI_SUBSYS_CLOSE:
236 case HPI_SUBSYS_GET_INFO:
237 case HPI_SUBSYS_DRIVER_UNLOAD:
238 case HPI_SUBSYS_DRIVER_LOAD:
239 case HPI_SUBSYS_FIND_ADAPTERS:
240 /* messages that should not get here */
241 phr->error = HPI_ERROR_UNIMPLEMENTED;
242 break;
243 case HPI_SUBSYS_CREATE_ADAPTER:
244 subsys_create_adapter(phm, phr);
245 break;
246 case HPI_SUBSYS_DELETE_ADAPTER:
247 subsys_delete_adapter(phm, phr);
248 break;
249 default:
250 phr->error = HPI_ERROR_INVALID_FUNC;
251 break;
252 }
253}
254
255static void control_message(struct hpi_adapter_obj *pao,
256 struct hpi_message *phm, struct hpi_response *phr)
257{
258
259 struct hpi_hw_obj *phw = pao->priv;
260
261 switch (phm->function) {
262 case HPI_CONTROL_GET_STATE:
263 if (pao->has_control_cache) {
264 rmb(); /* make sure we see updates DM_aed from DSP */
265 if (hpi_check_control_cache(phw->p_cache, phm, phr))
266 break;
267 }
268 hw_message(pao, phm, phr);
269 break;
270 case HPI_CONTROL_GET_INFO:
271 hw_message(pao, phm, phr);
272 break;
273 case HPI_CONTROL_SET_STATE:
274 hw_message(pao, phm, phr);
275 if (pao->has_control_cache)
276 hpi_sync_control_cache(phw->p_cache, phm, phr);
277 break;
278 default:
279 phr->error = HPI_ERROR_INVALID_FUNC;
280 break;
281 }
282}
283
284static void adapter_message(struct hpi_adapter_obj *pao,
285 struct hpi_message *phm, struct hpi_response *phr)
286{
287 switch (phm->function) {
288 default:
289 hw_message(pao, phm, phr);
290 break;
291 }
292}
293
294static void outstream_message(struct hpi_adapter_obj *pao,
295 struct hpi_message *phm, struct hpi_response *phr)
296{
297
298 if (phm->obj_index >= HPI_MAX_STREAMS) {
299 phr->error = HPI_ERROR_INVALID_STREAM;
300 HPI_DEBUG_LOG(WARNING,
301 "message referencing invalid stream %d "
302 "on adapter index %d\n", phm->obj_index,
303 phm->adapter_index);
304 return;
305 }
306
307 switch (phm->function) {
308 case HPI_OSTREAM_WRITE:
309 outstream_write(pao, phm, phr);
310 break;
311 case HPI_OSTREAM_GET_INFO:
312 outstream_get_info(pao, phm, phr);
313 break;
314 case HPI_OSTREAM_HOSTBUFFER_ALLOC:
315 outstream_host_buffer_allocate(pao, phm, phr);
316 break;
317 case HPI_OSTREAM_HOSTBUFFER_GET_INFO:
318 outstream_host_buffer_get_info(pao, phm, phr);
319 break;
320 case HPI_OSTREAM_HOSTBUFFER_FREE:
321 outstream_host_buffer_free(pao, phm, phr);
322 break;
323 case HPI_OSTREAM_START:
324 outstream_start(pao, phm, phr);
325 break;
326 case HPI_OSTREAM_OPEN:
327 outstream_open(pao, phm, phr);
328 break;
329 case HPI_OSTREAM_RESET:
330 outstream_reset(pao, phm, phr);
331 break;
332 default:
333 hw_message(pao, phm, phr);
334 break;
335 }
336}
337
338static void instream_message(struct hpi_adapter_obj *pao,
339 struct hpi_message *phm, struct hpi_response *phr)
340{
341
342 if (phm->obj_index >= HPI_MAX_STREAMS) {
343 phr->error = HPI_ERROR_INVALID_STREAM;
344 HPI_DEBUG_LOG(WARNING,
345 "message referencing invalid stream %d "
346 "on adapter index %d\n", phm->obj_index,
347 phm->adapter_index);
348 return;
349 }
350
351 switch (phm->function) {
352 case HPI_ISTREAM_READ:
353 instream_read(pao, phm, phr);
354 break;
355 case HPI_ISTREAM_GET_INFO:
356 instream_get_info(pao, phm, phr);
357 break;
358 case HPI_ISTREAM_HOSTBUFFER_ALLOC:
359 instream_host_buffer_allocate(pao, phm, phr);
360 break;
361 case HPI_ISTREAM_HOSTBUFFER_GET_INFO:
362 instream_host_buffer_get_info(pao, phm, phr);
363 break;
364 case HPI_ISTREAM_HOSTBUFFER_FREE:
365 instream_host_buffer_free(pao, phm, phr);
366 break;
367 case HPI_ISTREAM_START:
368 instream_start(pao, phm, phr);
369 break;
370 default:
371 hw_message(pao, phm, phr);
372 break;
373 }
374}
375
376/*****************************************************************************/
377/** Entry point to this HPI backend
378 * All calls to the HPI start here
379 */
380void HPI_6205(struct hpi_message *phm, struct hpi_response *phr)
381{
382 struct hpi_adapter_obj *pao = NULL;
383
384 /* subsytem messages are processed by every HPI.
385 * All other messages are ignored unless the adapter index matches
386 * an adapter in the HPI
387 */
388 HPI_DEBUG_LOG(DEBUG, "HPI obj=%d, func=%d\n", phm->object,
389 phm->function);
390
391 /* if Dsp has crashed then do not communicate with it any more */
392 if (phm->object != HPI_OBJ_SUBSYSTEM) {
393 pao = hpi_find_adapter(phm->adapter_index);
394 if (!pao) {
395 HPI_DEBUG_LOG(DEBUG,
396 " %d,%d refused, for another HPI?\n",
397 phm->object, phm->function);
398 return;
399 }
400
401 if ((pao->dsp_crashed >= 10)
402 && (phm->function != HPI_ADAPTER_DEBUG_READ)) {
403 /* allow last resort debug read even after crash */
404 hpi_init_response(phr, phm->object, phm->function,
405 HPI_ERROR_DSP_HARDWARE);
406 HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n",
407 phm->object, phm->function);
408 return;
409 }
410 }
411
412 /* Init default response */
413 if (phm->function != HPI_SUBSYS_CREATE_ADAPTER)
414 hpi_init_response(phr, phm->object, phm->function,
415 HPI_ERROR_PROCESSING_MESSAGE);
416
417 HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
418 switch (phm->type) {
419 case HPI_TYPE_MESSAGE:
420 switch (phm->object) {
421 case HPI_OBJ_SUBSYSTEM:
422 subsys_message(phm, phr);
423 break;
424
425 case HPI_OBJ_ADAPTER:
426 phr->size =
427 sizeof(struct hpi_response_header) +
428 sizeof(struct hpi_adapter_res);
429 adapter_message(pao, phm, phr);
430 break;
431
432 case HPI_OBJ_CONTROLEX:
433 case HPI_OBJ_CONTROL:
434 control_message(pao, phm, phr);
435 break;
436
437 case HPI_OBJ_OSTREAM:
438 outstream_message(pao, phm, phr);
439 break;
440
441 case HPI_OBJ_ISTREAM:
442 instream_message(pao, phm, phr);
443 break;
444
445 default:
446 hw_message(pao, phm, phr);
447 break;
448 }
449 break;
450
451 default:
452 phr->error = HPI_ERROR_INVALID_TYPE;
453 break;
454 }
455}
456
457/*****************************************************************************/
458/* SUBSYSTEM */
459
460/** Create an adapter object and initialise it based on resource information
461 * passed in in the message
462 * *** NOTE - you cannot use this function AND the FindAdapters function at the
463 * same time, the application must use only one of them to get the adapters ***
464 */
465static void subsys_create_adapter(struct hpi_message *phm,
466 struct hpi_response *phr)
467{
468 /* create temp adapter obj, because we don't know what index yet */
469 struct hpi_adapter_obj ao;
470 u32 os_error_code;
471 u16 err;
472
473 HPI_DEBUG_LOG(DEBUG, " subsys_create_adapter\n");
474
475 memset(&ao, 0, sizeof(ao));
476
477 /* this HPI only creates adapters for TI/PCI devices */
478 if (phm->u.s.resource.bus_type != HPI_BUS_PCI)
479 return;
480 if (phm->u.s.resource.r.pci->vendor_id != HPI_PCI_VENDOR_ID_TI)
481 return;
482 if (phm->u.s.resource.r.pci->device_id != HPI_PCI_DEV_ID_DSP6205)
483 return;
484
485 ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL);
486 if (!ao.priv) {
487 HPI_DEBUG_LOG(ERROR, "cant get mem for adapter object\n");
488 phr->error = HPI_ERROR_MEMORY_ALLOC;
489 return;
490 }
491
492 ao.pci = *phm->u.s.resource.r.pci;
493 err = create_adapter_obj(&ao, &os_error_code);
494 if (!err)
495 err = hpi_add_adapter(&ao);
496 if (err) {
497 phr->u.s.data = os_error_code;
498 delete_adapter_obj(&ao);
499 phr->error = err;
500 return;
501 }
502
503 phr->u.s.aw_adapter_list[ao.index] = ao.adapter_type;
504 phr->u.s.adapter_index = ao.index;
505 phr->u.s.num_adapters++;
506 phr->error = 0;
507}
508
509/** delete an adapter - required by WDM driver */
510static void subsys_delete_adapter(struct hpi_message *phm,
511 struct hpi_response *phr)
512{
513 struct hpi_adapter_obj *pao;
514 struct hpi_hw_obj *phw;
515
516 pao = hpi_find_adapter(phm->adapter_index);
517 if (!pao) {
518 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
519 return;
520 }
521 phw = (struct hpi_hw_obj *)pao->priv;
522 /* reset adapter h/w */
523 /* Reset C6713 #1 */
524 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
525 /* reset C6205 */
526 iowrite32(C6205_HDCR_WARMRESET, phw->prHDCR);
527
528 delete_adapter_obj(pao);
529 phr->error = 0;
530}
531
532/** Create adapter object
533 allocate buffers, bootload DSPs, initialise control cache
534*/
535static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
536 u32 *pos_error_code)
537{
538 struct hpi_hw_obj *phw = pao->priv;
539 struct bus_master_interface *interface;
540 u32 phys_addr;
541#ifndef HPI6205_NO_HSR_POLL
542 u32 time_out = HPI6205_TIMEOUT;
543 u32 temp1;
544#endif
545 int i;
546 u16 err;
547
548 /* init error reporting */
549 pao->dsp_crashed = 0;
550
551 for (i = 0; i < HPI_MAX_STREAMS; i++)
552 phw->flag_outstream_just_reset[i] = 1;
553
554 /* The C6205 memory area 1 is 8Mbyte window into DSP registers */
555 phw->prHSR =
556 pao->pci.ap_mem_base[1] +
557 C6205_BAR1_HSR / sizeof(*pao->pci.ap_mem_base[1]);
558 phw->prHDCR =
559 pao->pci.ap_mem_base[1] +
560 C6205_BAR1_HDCR / sizeof(*pao->pci.ap_mem_base[1]);
561 phw->prDSPP =
562 pao->pci.ap_mem_base[1] +
563 C6205_BAR1_DSPP / sizeof(*pao->pci.ap_mem_base[1]);
564
565 pao->has_control_cache = 0;
566
567 if (hpios_locked_mem_alloc(&phw->h_locked_mem,
568 sizeof(struct bus_master_interface),
569 pao->pci.p_os_data))
570 phw->p_interface_buffer = NULL;
571 else if (hpios_locked_mem_get_virt_addr(&phw->h_locked_mem,
572 (void *)&phw->p_interface_buffer))
573 phw->p_interface_buffer = NULL;
574
575 HPI_DEBUG_LOG(DEBUG, "interface buffer address %p\n",
576 phw->p_interface_buffer);
577
578 if (phw->p_interface_buffer) {
579 memset((void *)phw->p_interface_buffer, 0,
580 sizeof(struct bus_master_interface));
581 phw->p_interface_buffer->dsp_ack = H620_HIF_UNKNOWN;
582 }
583
584 err = adapter_boot_load_dsp(pao, pos_error_code);
585 if (err)
586 /* no need to clean up as SubSysCreateAdapter */
587 /* calls DeleteAdapter on error. */
588 return err;
589
590 HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
591
592 /* allow boot load even if mem alloc wont work */
593 if (!phw->p_interface_buffer)
594 return hpi6205_error(0, HPI_ERROR_MEMORY_ALLOC);
595
596 interface = phw->p_interface_buffer;
597
598#ifndef HPI6205_NO_HSR_POLL
599 /* wait for first interrupt indicating the DSP init is done */
600 time_out = HPI6205_TIMEOUT * 10;
601 temp1 = 0;
602 while (((temp1 & C6205_HSR_INTSRC) == 0) && --time_out)
603 temp1 = ioread32(phw->prHSR);
604
605 if (temp1 & C6205_HSR_INTSRC)
606 HPI_DEBUG_LOG(INFO,
607 "interrupt confirming DSP code running OK\n");
608 else {
609 HPI_DEBUG_LOG(ERROR,
610 "timed out waiting for interrupt "
611 "confirming DSP code running\n");
612 return hpi6205_error(0, HPI6205_ERROR_6205_NO_IRQ);
613 }
614
615 /* reset the interrupt */
616 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
617#endif
618
619 /* make sure the DSP has started ok */
620 if (!wait_dsp_ack(phw, H620_HIF_RESET, HPI6205_TIMEOUT * 10)) {
621 HPI_DEBUG_LOG(ERROR, "timed out waiting reset state \n");
622 return hpi6205_error(0, HPI6205_ERROR_6205_INIT_FAILED);
623 }
624 /* Note that *pao, *phw are zeroed after allocation,
625 * so pointers and flags are NULL by default.
626 * Allocate bus mastering control cache buffer and tell the DSP about it
627 */
628 if (interface->control_cache.number_of_controls) {
629 void *p_control_cache_virtual;
630
631 err = hpios_locked_mem_alloc(&phw->h_control_cache,
632 interface->control_cache.size_in_bytes,
633 pao->pci.p_os_data);
634 if (!err)
635 err = hpios_locked_mem_get_virt_addr(&phw->
636 h_control_cache, &p_control_cache_virtual);
637 if (!err) {
638 memset(p_control_cache_virtual, 0,
639 interface->control_cache.size_in_bytes);
640
641 phw->p_cache =
642 hpi_alloc_control_cache(interface->
643 control_cache.number_of_controls,
644 interface->control_cache.size_in_bytes,
645 (struct hpi_control_cache_info *)
646 p_control_cache_virtual);
647 }
648 if (!err) {
649 err = hpios_locked_mem_get_phys_addr(&phw->
650 h_control_cache, &phys_addr);
651 interface->control_cache.physical_address32 =
652 phys_addr;
653 }
654
655 if (!err)
656 pao->has_control_cache = 1;
657 else {
658 if (hpios_locked_mem_valid(&phw->h_control_cache))
659 hpios_locked_mem_free(&phw->h_control_cache);
660 pao->has_control_cache = 0;
661 }
662 }
663 /* allocate bus mastering async buffer and tell the DSP about it */
664 if (interface->async_buffer.b.size) {
665 err = hpios_locked_mem_alloc(&phw->h_async_event_buffer,
666 interface->async_buffer.b.size *
667 sizeof(struct hpi_async_event), pao->pci.p_os_data);
668 if (!err)
669 err = hpios_locked_mem_get_virt_addr
670 (&phw->h_async_event_buffer, (void *)
671 &phw->p_async_event_buffer);
672 if (!err)
673 memset((void *)phw->p_async_event_buffer, 0,
674 interface->async_buffer.b.size *
675 sizeof(struct hpi_async_event));
676 if (!err) {
677 err = hpios_locked_mem_get_phys_addr
678 (&phw->h_async_event_buffer, &phys_addr);
679 interface->async_buffer.physical_address32 =
680 phys_addr;
681 }
682 if (err) {
683 if (hpios_locked_mem_valid(&phw->
684 h_async_event_buffer)) {
685 hpios_locked_mem_free
686 (&phw->h_async_event_buffer);
687 phw->p_async_event_buffer = NULL;
688 }
689 }
690 }
691 send_dsp_command(phw, H620_HIF_IDLE);
692
693 {
694 struct hpi_message hM;
695 struct hpi_response hR;
696 u32 max_streams;
697
698 HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
699 memset(&hM, 0, sizeof(hM));
700 hM.type = HPI_TYPE_MESSAGE;
701 hM.size = sizeof(hM);
702 hM.object = HPI_OBJ_ADAPTER;
703 hM.function = HPI_ADAPTER_GET_INFO;
704 hM.adapter_index = 0;
705 memset(&hR, 0, sizeof(hR));
706 hR.size = sizeof(hR);
707
708 err = message_response_sequence(pao, &hM, &hR);
709 if (err) {
710 HPI_DEBUG_LOG(ERROR, "message transport error %d\n",
711 err);
712 return err;
713 }
714 if (hR.error)
715 return hR.error;
716
717 pao->adapter_type = hR.u.a.adapter_type;
718 pao->index = hR.u.a.adapter_index;
719
720 max_streams = hR.u.a.num_outstreams + hR.u.a.num_instreams;
721
722 hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
723 65536, pao->pci.p_os_data);
724
725 HPI_DEBUG_LOG(VERBOSE,
726 "got adapter info type %x index %d serial %d\n",
727 hR.u.a.adapter_type, hR.u.a.adapter_index,
728 hR.u.a.serial_number);
729 }
730
731 pao->open = 0; /* upon creation the adapter is closed */
732
733 HPI_DEBUG_LOG(INFO, "bootload DSP OK\n");
734 return 0;
735}
736
737/** Free memory areas allocated by adapter
738 * this routine is called from SubSysDeleteAdapter,
739 * and SubSysCreateAdapter if duplicate index
740*/
741static void delete_adapter_obj(struct hpi_adapter_obj *pao)
742{
743 struct hpi_hw_obj *phw;
744 int i;
745
746 phw = pao->priv;
747
748 if (hpios_locked_mem_valid(&phw->h_async_event_buffer)) {
749 hpios_locked_mem_free(&phw->h_async_event_buffer);
750 phw->p_async_event_buffer = NULL;
751 }
752
753 if (hpios_locked_mem_valid(&phw->h_control_cache)) {
754 hpios_locked_mem_free(&phw->h_control_cache);
755 hpi_free_control_cache(phw->p_cache);
756 }
757
758 if (hpios_locked_mem_valid(&phw->h_locked_mem)) {
759 hpios_locked_mem_free(&phw->h_locked_mem);
760 phw->p_interface_buffer = NULL;
761 }
762
763 for (i = 0; i < HPI_MAX_STREAMS; i++)
764 if (hpios_locked_mem_valid(&phw->instream_host_buffers[i])) {
765 hpios_locked_mem_free(&phw->instream_host_buffers[i]);
766 /*?phw->InStreamHostBuffers[i] = NULL; */
767 phw->instream_host_buffer_size[i] = 0;
768 }
769
770 for (i = 0; i < HPI_MAX_STREAMS; i++)
771 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[i])) {
772 hpios_locked_mem_free(&phw->outstream_host_buffers
773 [i]);
774 phw->outstream_host_buffer_size[i] = 0;
775 }
776
777 hpios_locked_mem_unprepare(pao->pci.p_os_data);
778
779 hpi_delete_adapter(pao);
780 kfree(phw);
781}
782
783/*****************************************************************************/
784/* OutStream Host buffer functions */
785
786/** Allocate or attach buffer for busmastering
787*/
788static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao,
789 struct hpi_message *phm, struct hpi_response *phr)
790{
791 u16 err = 0;
792 u32 command = phm->u.d.u.buffer.command;
793 struct hpi_hw_obj *phw = pao->priv;
794 struct bus_master_interface *interface = phw->p_interface_buffer;
795
796 hpi_init_response(phr, phm->object, phm->function, 0);
797
798 if (command == HPI_BUFFER_CMD_EXTERNAL
799 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
800 /* ALLOC phase, allocate a buffer with power of 2 size,
801 get its bus address for PCI bus mastering
802 */
803 phm->u.d.u.buffer.buffer_size =
804 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
805 /* return old size and allocated size,
806 so caller can detect change */
807 phr->u.d.u.stream_info.data_available =
808 phw->outstream_host_buffer_size[phm->obj_index];
809 phr->u.d.u.stream_info.buffer_size =
810 phm->u.d.u.buffer.buffer_size;
811
812 if (phw->outstream_host_buffer_size[phm->obj_index] ==
813 phm->u.d.u.buffer.buffer_size) {
814 /* Same size, no action required */
815 return;
816 }
817
818 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
819 obj_index]))
820 hpios_locked_mem_free(&phw->outstream_host_buffers
821 [phm->obj_index]);
822
823 err = hpios_locked_mem_alloc(&phw->outstream_host_buffers
824 [phm->obj_index], phm->u.d.u.buffer.buffer_size,
825 pao->pci.p_os_data);
826
827 if (err) {
828 phr->error = HPI_ERROR_INVALID_DATASIZE;
829 phw->outstream_host_buffer_size[phm->obj_index] = 0;
830 return;
831 }
832
833 err = hpios_locked_mem_get_phys_addr
834 (&phw->outstream_host_buffers[phm->obj_index],
835 &phm->u.d.u.buffer.pci_address);
836 /* get the phys addr into msg for single call alloc caller
837 * needs to do this for split alloc (or use the same message)
838 * return the phy address for split alloc in the respose too
839 */
840 phr->u.d.u.stream_info.auxiliary_data_available =
841 phm->u.d.u.buffer.pci_address;
842
843 if (err) {
844 hpios_locked_mem_free(&phw->outstream_host_buffers
845 [phm->obj_index]);
846 phw->outstream_host_buffer_size[phm->obj_index] = 0;
847 phr->error = HPI_ERROR_MEMORY_ALLOC;
848 return;
849 }
850 }
851
852 if (command == HPI_BUFFER_CMD_EXTERNAL
853 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
854 /* GRANT phase. Set up the BBM status, tell the DSP about
855 the buffer so it can start using BBM.
856 */
857 struct hpi_hostbuffer_status *status;
858
859 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
860 buffer_size - 1)) {
861 HPI_DEBUG_LOG(ERROR,
862 "buffer size must be 2^N not %d\n",
863 phm->u.d.u.buffer.buffer_size);
864 phr->error = HPI_ERROR_INVALID_DATASIZE;
865 return;
866 }
867 phw->outstream_host_buffer_size[phm->obj_index] =
868 phm->u.d.u.buffer.buffer_size;
869 status = &interface->outstream_host_buffer_status[phm->
870 obj_index];
871 status->samples_processed = 0;
872 status->stream_state = HPI_STATE_STOPPED;
873 status->dSP_index = 0;
874 status->host_index = status->dSP_index;
875 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
876
877 hw_message(pao, phm, phr);
878
879 if (phr->error
880 && hpios_locked_mem_valid(&phw->
881 outstream_host_buffers[phm->obj_index])) {
882 hpios_locked_mem_free(&phw->outstream_host_buffers
883 [phm->obj_index]);
884 phw->outstream_host_buffer_size[phm->obj_index] = 0;
885 }
886 }
887}
888
889static void outstream_host_buffer_get_info(struct hpi_adapter_obj *pao,
890 struct hpi_message *phm, struct hpi_response *phr)
891{
892 struct hpi_hw_obj *phw = pao->priv;
893 struct bus_master_interface *interface = phw->p_interface_buffer;
894 struct hpi_hostbuffer_status *status;
895 u8 *p_bbm_data;
896
897 if (hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
898 obj_index])) {
899 if (hpios_locked_mem_get_virt_addr(&phw->
900 outstream_host_buffers[phm->obj_index],
901 (void *)&p_bbm_data)) {
902 phr->error = HPI_ERROR_INVALID_OPERATION;
903 return;
904 }
905 status = &interface->outstream_host_buffer_status[phm->
906 obj_index];
907 hpi_init_response(phr, HPI_OBJ_OSTREAM,
908 HPI_OSTREAM_HOSTBUFFER_GET_INFO, 0);
909 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
910 phr->u.d.u.hostbuffer_info.p_status = status;
911 } else {
912 hpi_init_response(phr, HPI_OBJ_OSTREAM,
913 HPI_OSTREAM_HOSTBUFFER_GET_INFO,
914 HPI_ERROR_INVALID_OPERATION);
915 }
916}
917
918static void outstream_host_buffer_free(struct hpi_adapter_obj *pao,
919 struct hpi_message *phm, struct hpi_response *phr)
920{
921 struct hpi_hw_obj *phw = pao->priv;
922 u32 command = phm->u.d.u.buffer.command;
923
924 if (phw->outstream_host_buffer_size[phm->obj_index]) {
925 if (command == HPI_BUFFER_CMD_EXTERNAL
926 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
927 phw->outstream_host_buffer_size[phm->obj_index] = 0;
928 hw_message(pao, phm, phr);
929 /* Tell adapter to stop using the host buffer. */
930 }
931 if (command == HPI_BUFFER_CMD_EXTERNAL
932 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
933 hpios_locked_mem_free(&phw->outstream_host_buffers
934 [phm->obj_index]);
935 }
936 /* Should HPI_ERROR_INVALID_OPERATION be returned
937 if no host buffer is allocated? */
938 else
939 hpi_init_response(phr, HPI_OBJ_OSTREAM,
940 HPI_OSTREAM_HOSTBUFFER_FREE, 0);
941
942}
943
944static long outstream_get_space_available(struct hpi_hostbuffer_status
945 *status)
946{
947 return status->size_in_bytes - ((long)(status->host_index) -
948 (long)(status->dSP_index));
949}
950
951static void outstream_write(struct hpi_adapter_obj *pao,
952 struct hpi_message *phm, struct hpi_response *phr)
953{
954 struct hpi_hw_obj *phw = pao->priv;
955 struct bus_master_interface *interface = phw->p_interface_buffer;
956 struct hpi_hostbuffer_status *status;
957 long space_available;
958
959 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
960 /* there is no BBM buffer, write via message */
961 hw_message(pao, phm, phr);
962 return;
963 }
964
965 hpi_init_response(phr, phm->object, phm->function, 0);
966 status = &interface->outstream_host_buffer_status[phm->obj_index];
967
968 if (phw->flag_outstream_just_reset[phm->obj_index]) {
969 /* Format can only change after reset. Must tell DSP. */
970 u16 function = phm->function;
971 phw->flag_outstream_just_reset[phm->obj_index] = 0;
972 phm->function = HPI_OSTREAM_SET_FORMAT;
973 hw_message(pao, phm, phr); /* send the format to the DSP */
974 phm->function = function;
975 if (phr->error)
976 return;
977 }
978#if 1
979 if (phw->flag_outstream_just_reset[phm->obj_index]) {
980 /* First OutStremWrite() call following reset will write data to the
981 adapter's buffers, reducing delay before stream can start
982 */
983 int partial_write = 0;
984 unsigned int original_size = 0;
985
986 /* Send the first buffer to the DSP the old way. */
987 /* Limit size of first transfer - */
988 /* expect that this will not usually be triggered. */
989 if (phm->u.d.u.data.data_size > HPI6205_SIZEOF_DATA) {
990 partial_write = 1;
991 original_size = phm->u.d.u.data.data_size;
992 phm->u.d.u.data.data_size = HPI6205_SIZEOF_DATA;
993 }
994 /* write it */
995 phm->function = HPI_OSTREAM_WRITE;
996 hw_message(pao, phm, phr);
997 /* update status information that the DSP would typically
998 * update (and will update next time the DSP
999 * buffer update task reads data from the host BBM buffer)
1000 */
1001 status->auxiliary_data_available = phm->u.d.u.data.data_size;
1002 status->host_index += phm->u.d.u.data.data_size;
1003 status->dSP_index += phm->u.d.u.data.data_size;
1004
1005 /* if we did a full write, we can return from here. */
1006 if (!partial_write)
1007 return;
1008
1009 /* tweak buffer parameters and let the rest of the */
1010 /* buffer land in internal BBM buffer */
1011 phm->u.d.u.data.data_size =
1012 original_size - HPI6205_SIZEOF_DATA;
1013 phm->u.d.u.data.pb_data += HPI6205_SIZEOF_DATA;
1014 }
1015#endif
1016
1017 space_available = outstream_get_space_available(status);
1018 if (space_available < (long)phm->u.d.u.data.data_size) {
1019 phr->error = HPI_ERROR_INVALID_DATASIZE;
1020 return;
1021 }
1022
1023 /* HostBuffers is used to indicate host buffer is internally allocated.
1024 otherwise, assumed external, data written externally */
1025 if (phm->u.d.u.data.pb_data
1026 && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm->
1027 obj_index])) {
1028 u8 *p_bbm_data;
1029 long l_first_write;
1030 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1031
1032 if (hpios_locked_mem_get_virt_addr(&phw->
1033 outstream_host_buffers[phm->obj_index],
1034 (void *)&p_bbm_data)) {
1035 phr->error = HPI_ERROR_INVALID_OPERATION;
1036 return;
1037 }
1038
1039 /* either all data,
1040 or enough to fit from current to end of BBM buffer */
1041 l_first_write =
1042 min(phm->u.d.u.data.data_size,
1043 status->size_in_bytes -
1044 (status->host_index & (status->size_in_bytes - 1)));
1045
1046 memcpy(p_bbm_data +
1047 (status->host_index & (status->size_in_bytes - 1)),
1048 p_app_data, l_first_write);
1049 /* remaining data if any */
1050 memcpy(p_bbm_data, p_app_data + l_first_write,
1051 phm->u.d.u.data.data_size - l_first_write);
1052 }
1053 status->host_index += phm->u.d.u.data.data_size;
1054}
1055
1056static void outstream_get_info(struct hpi_adapter_obj *pao,
1057 struct hpi_message *phm, struct hpi_response *phr)
1058{
1059 struct hpi_hw_obj *phw = pao->priv;
1060 struct bus_master_interface *interface = phw->p_interface_buffer;
1061 struct hpi_hostbuffer_status *status;
1062
1063 if (!phw->outstream_host_buffer_size[phm->obj_index]) {
1064 hw_message(pao, phm, phr);
1065 return;
1066 }
1067
1068 hpi_init_response(phr, phm->object, phm->function, 0);
1069
1070 status = &interface->outstream_host_buffer_status[phm->obj_index];
1071
1072 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1073 phr->u.d.u.stream_info.samples_transferred =
1074 status->samples_processed;
1075 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1076 phr->u.d.u.stream_info.data_available =
1077 status->size_in_bytes - outstream_get_space_available(status);
1078 phr->u.d.u.stream_info.auxiliary_data_available =
1079 status->auxiliary_data_available;
1080}
1081
1082static void outstream_start(struct hpi_adapter_obj *pao,
1083 struct hpi_message *phm, struct hpi_response *phr)
1084{
1085 hw_message(pao, phm, phr);
1086}
1087
1088static void outstream_reset(struct hpi_adapter_obj *pao,
1089 struct hpi_message *phm, struct hpi_response *phr)
1090{
1091 struct hpi_hw_obj *phw = pao->priv;
1092 phw->flag_outstream_just_reset[phm->obj_index] = 1;
1093 hw_message(pao, phm, phr);
1094}
1095
1096static void outstream_open(struct hpi_adapter_obj *pao,
1097 struct hpi_message *phm, struct hpi_response *phr)
1098{
1099 outstream_reset(pao, phm, phr);
1100}
1101
1102/*****************************************************************************/
1103/* InStream Host buffer functions */
1104
1105static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao,
1106 struct hpi_message *phm, struct hpi_response *phr)
1107{
1108 u16 err = 0;
1109 u32 command = phm->u.d.u.buffer.command;
1110 struct hpi_hw_obj *phw = pao->priv;
1111 struct bus_master_interface *interface = phw->p_interface_buffer;
1112
1113 hpi_init_response(phr, phm->object, phm->function, 0);
1114
1115 if (command == HPI_BUFFER_CMD_EXTERNAL
1116 || command == HPI_BUFFER_CMD_INTERNAL_ALLOC) {
1117
1118 phm->u.d.u.buffer.buffer_size =
1119 roundup_pow_of_two(phm->u.d.u.buffer.buffer_size);
1120 phr->u.d.u.stream_info.data_available =
1121 phw->instream_host_buffer_size[phm->obj_index];
1122 phr->u.d.u.stream_info.buffer_size =
1123 phm->u.d.u.buffer.buffer_size;
1124
1125 if (phw->instream_host_buffer_size[phm->obj_index] ==
1126 phm->u.d.u.buffer.buffer_size) {
1127 /* Same size, no action required */
1128 return;
1129 }
1130
1131 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1132 obj_index]))
1133 hpios_locked_mem_free(&phw->instream_host_buffers
1134 [phm->obj_index]);
1135
1136 err = hpios_locked_mem_alloc(&phw->instream_host_buffers[phm->
1137 obj_index], phm->u.d.u.buffer.buffer_size,
1138 pao->pci.p_os_data);
1139
1140 if (err) {
1141 phr->error = HPI_ERROR_INVALID_DATASIZE;
1142 phw->instream_host_buffer_size[phm->obj_index] = 0;
1143 return;
1144 }
1145
1146 err = hpios_locked_mem_get_phys_addr
1147 (&phw->instream_host_buffers[phm->obj_index],
1148 &phm->u.d.u.buffer.pci_address);
1149 /* get the phys addr into msg for single call alloc. Caller
1150 needs to do this for split alloc so return the phy address */
1151 phr->u.d.u.stream_info.auxiliary_data_available =
1152 phm->u.d.u.buffer.pci_address;
1153 if (err) {
1154 hpios_locked_mem_free(&phw->instream_host_buffers
1155 [phm->obj_index]);
1156 phw->instream_host_buffer_size[phm->obj_index] = 0;
1157 phr->error = HPI_ERROR_MEMORY_ALLOC;
1158 return;
1159 }
1160 }
1161
1162 if (command == HPI_BUFFER_CMD_EXTERNAL
1163 || command == HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER) {
1164 struct hpi_hostbuffer_status *status;
1165
1166 if (phm->u.d.u.buffer.buffer_size & (phm->u.d.u.buffer.
1167 buffer_size - 1)) {
1168 HPI_DEBUG_LOG(ERROR,
1169 "buffer size must be 2^N not %d\n",
1170 phm->u.d.u.buffer.buffer_size);
1171 phr->error = HPI_ERROR_INVALID_DATASIZE;
1172 return;
1173 }
1174
1175 phw->instream_host_buffer_size[phm->obj_index] =
1176 phm->u.d.u.buffer.buffer_size;
1177 status = &interface->instream_host_buffer_status[phm->
1178 obj_index];
1179 status->samples_processed = 0;
1180 status->stream_state = HPI_STATE_STOPPED;
1181 status->dSP_index = 0;
1182 status->host_index = status->dSP_index;
1183 status->size_in_bytes = phm->u.d.u.buffer.buffer_size;
1184
1185 hw_message(pao, phm, phr);
1186 if (phr->error
1187 && hpios_locked_mem_valid(&phw->
1188 instream_host_buffers[phm->obj_index])) {
1189 hpios_locked_mem_free(&phw->instream_host_buffers
1190 [phm->obj_index]);
1191 phw->instream_host_buffer_size[phm->obj_index] = 0;
1192 }
1193 }
1194}
1195
1196static void instream_host_buffer_get_info(struct hpi_adapter_obj *pao,
1197 struct hpi_message *phm, struct hpi_response *phr)
1198{
1199 struct hpi_hw_obj *phw = pao->priv;
1200 struct bus_master_interface *interface = phw->p_interface_buffer;
1201 struct hpi_hostbuffer_status *status;
1202 u8 *p_bbm_data;
1203
1204 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1205 obj_index])) {
1206 if (hpios_locked_mem_get_virt_addr(&phw->
1207 instream_host_buffers[phm->obj_index],
1208 (void *)&p_bbm_data)) {
1209 phr->error = HPI_ERROR_INVALID_OPERATION;
1210 return;
1211 }
1212 status = &interface->instream_host_buffer_status[phm->
1213 obj_index];
1214 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1215 HPI_ISTREAM_HOSTBUFFER_GET_INFO, 0);
1216 phr->u.d.u.hostbuffer_info.p_buffer = p_bbm_data;
1217 phr->u.d.u.hostbuffer_info.p_status = status;
1218 } else {
1219 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1220 HPI_ISTREAM_HOSTBUFFER_GET_INFO,
1221 HPI_ERROR_INVALID_OPERATION);
1222 }
1223}
1224
1225static void instream_host_buffer_free(struct hpi_adapter_obj *pao,
1226 struct hpi_message *phm, struct hpi_response *phr)
1227{
1228 struct hpi_hw_obj *phw = pao->priv;
1229 u32 command = phm->u.d.u.buffer.command;
1230
1231 if (phw->instream_host_buffer_size[phm->obj_index]) {
1232 if (command == HPI_BUFFER_CMD_EXTERNAL
1233 || command == HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER) {
1234 phw->instream_host_buffer_size[phm->obj_index] = 0;
1235 hw_message(pao, phm, phr);
1236 }
1237
1238 if (command == HPI_BUFFER_CMD_EXTERNAL
1239 || command == HPI_BUFFER_CMD_INTERNAL_FREE)
1240 hpios_locked_mem_free(&phw->instream_host_buffers
1241 [phm->obj_index]);
1242
1243 } else {
1244 /* Should HPI_ERROR_INVALID_OPERATION be returned
1245 if no host buffer is allocated? */
1246 hpi_init_response(phr, HPI_OBJ_ISTREAM,
1247 HPI_ISTREAM_HOSTBUFFER_FREE, 0);
1248
1249 }
1250
1251}
1252
1253static void instream_start(struct hpi_adapter_obj *pao,
1254 struct hpi_message *phm, struct hpi_response *phr)
1255{
1256 hw_message(pao, phm, phr);
1257}
1258
1259static long instream_get_bytes_available(struct hpi_hostbuffer_status *status)
1260{
1261 return (long)(status->dSP_index) - (long)(status->host_index);
1262}
1263
1264static void instream_read(struct hpi_adapter_obj *pao,
1265 struct hpi_message *phm, struct hpi_response *phr)
1266{
1267 struct hpi_hw_obj *phw = pao->priv;
1268 struct bus_master_interface *interface = phw->p_interface_buffer;
1269 struct hpi_hostbuffer_status *status;
1270 long data_available;
1271 u8 *p_bbm_data;
1272 long l_first_read;
1273 u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data;
1274
1275 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1276 hw_message(pao, phm, phr);
1277 return;
1278 }
1279 hpi_init_response(phr, phm->object, phm->function, 0);
1280
1281 status = &interface->instream_host_buffer_status[phm->obj_index];
1282 data_available = instream_get_bytes_available(status);
1283 if (data_available < (long)phm->u.d.u.data.data_size) {
1284 phr->error = HPI_ERROR_INVALID_DATASIZE;
1285 return;
1286 }
1287
1288 if (hpios_locked_mem_valid(&phw->instream_host_buffers[phm->
1289 obj_index])) {
1290 if (hpios_locked_mem_get_virt_addr(&phw->
1291 instream_host_buffers[phm->obj_index],
1292 (void *)&p_bbm_data)) {
1293 phr->error = HPI_ERROR_INVALID_OPERATION;
1294 return;
1295 }
1296
1297 /* either all data,
1298 or enough to fit from current to end of BBM buffer */
1299 l_first_read =
1300 min(phm->u.d.u.data.data_size,
1301 status->size_in_bytes -
1302 (status->host_index & (status->size_in_bytes - 1)));
1303
1304 memcpy(p_app_data,
1305 p_bbm_data +
1306 (status->host_index & (status->size_in_bytes - 1)),
1307 l_first_read);
1308 /* remaining data if any */
1309 memcpy(p_app_data + l_first_read, p_bbm_data,
1310 phm->u.d.u.data.data_size - l_first_read);
1311 }
1312 status->host_index += phm->u.d.u.data.data_size;
1313}
1314
1315static void instream_get_info(struct hpi_adapter_obj *pao,
1316 struct hpi_message *phm, struct hpi_response *phr)
1317{
1318 struct hpi_hw_obj *phw = pao->priv;
1319 struct bus_master_interface *interface = phw->p_interface_buffer;
1320 struct hpi_hostbuffer_status *status;
1321 if (!phw->instream_host_buffer_size[phm->obj_index]) {
1322 hw_message(pao, phm, phr);
1323 return;
1324 }
1325
1326 status = &interface->instream_host_buffer_status[phm->obj_index];
1327
1328 hpi_init_response(phr, phm->object, phm->function, 0);
1329
1330 phr->u.d.u.stream_info.state = (u16)status->stream_state;
1331 phr->u.d.u.stream_info.samples_transferred =
1332 status->samples_processed;
1333 phr->u.d.u.stream_info.buffer_size = status->size_in_bytes;
1334 phr->u.d.u.stream_info.data_available =
1335 instream_get_bytes_available(status);
1336 phr->u.d.u.stream_info.auxiliary_data_available =
1337 status->auxiliary_data_available;
1338}
1339
1340/*****************************************************************************/
1341/* LOW-LEVEL */
1342#define HPI6205_MAX_FILES_TO_LOAD 2
1343
1344static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
1345 u32 *pos_error_code)
1346{
1347 struct hpi_hw_obj *phw = pao->priv;
1348 struct dsp_code dsp_code;
1349 u16 boot_code_id[HPI6205_MAX_FILES_TO_LOAD];
1350 u16 firmware_id = pao->pci.subsys_device_id;
1351 u32 temp;
1352 int dsp = 0, i = 0;
1353 u16 err = 0;
1354
1355 boot_code_id[0] = HPI_ADAPTER_ASI(0x6205);
1356
1357 /* special cases where firmware_id != subsys ID */
1358 switch (firmware_id) {
1359 case HPI_ADAPTER_FAMILY_ASI(0x5000):
1360 boot_code_id[0] = firmware_id;
1361 firmware_id = 0;
1362 break;
1363 case HPI_ADAPTER_FAMILY_ASI(0x5300):
1364 case HPI_ADAPTER_FAMILY_ASI(0x5400):
1365 case HPI_ADAPTER_FAMILY_ASI(0x6300):
1366 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6400);
1367 break;
1368 case HPI_ADAPTER_FAMILY_ASI(0x5600):
1369 case HPI_ADAPTER_FAMILY_ASI(0x6500):
1370 firmware_id = HPI_ADAPTER_FAMILY_ASI(0x6600);
1371 break;
1372 }
1373 boot_code_id[1] = firmware_id;
1374
1375 /* reset DSP by writing a 1 to the WARMRESET bit */
1376 temp = C6205_HDCR_WARMRESET;
1377 iowrite32(temp, phw->prHDCR);
1378 hpios_delay_micro_seconds(1000);
1379
1380 /* check that PCI i/f was configured by EEPROM */
1381 temp = ioread32(phw->prHSR);
1382 if ((temp & (C6205_HSR_CFGERR | C6205_HSR_EEREAD)) !=
1383 C6205_HSR_EEREAD)
1384 return hpi6205_error(0, HPI6205_ERROR_6205_EEPROM);
1385 temp |= 0x04;
1386 /* disable PINTA interrupt */
1387 iowrite32(temp, phw->prHSR);
1388
1389 /* check control register reports PCI boot mode */
1390 temp = ioread32(phw->prHDCR);
1391 if (!(temp & C6205_HDCR_PCIBOOT))
1392 return hpi6205_error(0, HPI6205_ERROR_6205_REG);
1393
1394 /* try writing a couple of numbers to the DSP page register */
1395 /* and reading them back. */
1396 temp = 1;
1397 iowrite32(temp, phw->prDSPP);
1398 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1399 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1400 temp = 2;
1401 iowrite32(temp, phw->prDSPP);
1402 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1403 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1404 temp = 3;
1405 iowrite32(temp, phw->prDSPP);
1406 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1407 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1408 /* reset DSP page to the correct number */
1409 temp = 0;
1410 iowrite32(temp, phw->prDSPP);
1411 if ((temp | C6205_DSPP_MAP1) != ioread32(phw->prDSPP))
1412 return hpi6205_error(0, HPI6205_ERROR_6205_DSPPAGE);
1413 phw->dsp_page = 0;
1414
1415 /* release 6713 from reset before 6205 is bootloaded.
1416 This ensures that the EMIF is inactive,
1417 and the 6713 HPI gets the correct bootmode etc
1418 */
1419 if (boot_code_id[1] != 0) {
1420 /* DSP 1 is a C6713 */
1421 /* CLKX0 <- '1' release the C6205 bootmode pulldowns */
1422 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002202);
1423 hpios_delay_micro_seconds(100);
1424 /* Reset the 6713 #1 - revB */
1425 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0);
1426
1427 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1428 boot_loader_read_mem32(pao, 0, 0);
1429
1430 hpios_delay_micro_seconds(100);
1431 /* Release C6713 from reset - revB */
1432 boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 4);
1433 hpios_delay_micro_seconds(100);
1434 }
1435
1436 for (dsp = 0; dsp < HPI6205_MAX_FILES_TO_LOAD; dsp++) {
1437 /* is there a DSP to load? */
1438 if (boot_code_id[dsp] == 0)
1439 continue;
1440
1441 err = boot_loader_config_emif(pao, dsp);
1442 if (err)
1443 return err;
1444
1445 err = boot_loader_test_internal_memory(pao, dsp);
1446 if (err)
1447 return err;
1448
1449 err = boot_loader_test_external_memory(pao, dsp);
1450 if (err)
1451 return err;
1452
1453 err = boot_loader_test_pld(pao, dsp);
1454 if (err)
1455 return err;
1456
1457 /* write the DSP code down into the DSPs memory */
1458 dsp_code.ps_dev = pao->pci.p_os_data;
1459 err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
1460 pos_error_code);
1461 if (err)
1462 return err;
1463
1464 while (1) {
1465 u32 length;
1466 u32 address;
1467 u32 type;
1468 u32 *pcode;
1469
1470 err = hpi_dsp_code_read_word(&dsp_code, &length);
1471 if (err)
1472 break;
1473 if (length == 0xFFFFFFFF)
1474 break; /* end of code */
1475
1476 err = hpi_dsp_code_read_word(&dsp_code, &address);
1477 if (err)
1478 break;
1479 err = hpi_dsp_code_read_word(&dsp_code, &type);
1480 if (err)
1481 break;
1482 err = hpi_dsp_code_read_block(length, &dsp_code,
1483 &pcode);
1484 if (err)
1485 break;
1486 for (i = 0; i < (int)length; i++) {
1487 err = boot_loader_write_mem32(pao, dsp,
1488 address, *pcode);
1489 if (err)
1490 break;
1491 /* dummy read every 4 words */
1492 /* for 6205 advisory 1.4.4 */
1493 if (i % 4 == 0)
1494 boot_loader_read_mem32(pao, dsp,
1495 address);
1496 pcode++;
1497 address += 4;
1498 }
1499
1500 }
1501 if (err) {
1502 hpi_dsp_code_close(&dsp_code);
1503 return err;
1504 }
1505
1506 /* verify code */
1507 hpi_dsp_code_rewind(&dsp_code);
1508 while (1) {
1509 u32 length = 0;
1510 u32 address = 0;
1511 u32 type = 0;
1512 u32 *pcode = NULL;
1513 u32 data = 0;
1514
1515 hpi_dsp_code_read_word(&dsp_code, &length);
1516 if (length == 0xFFFFFFFF)
1517 break; /* end of code */
1518
1519 hpi_dsp_code_read_word(&dsp_code, &address);
1520 hpi_dsp_code_read_word(&dsp_code, &type);
1521 hpi_dsp_code_read_block(length, &dsp_code, &pcode);
1522
1523 for (i = 0; i < (int)length; i++) {
1524 data = boot_loader_read_mem32(pao, dsp,
1525 address);
1526 if (data != *pcode) {
1527 err = 0;
1528 break;
1529 }
1530 pcode++;
1531 address += 4;
1532 }
1533 if (err)
1534 break;
1535 }
1536 hpi_dsp_code_close(&dsp_code);
1537 if (err)
1538 return err;
1539 }
1540
1541 /* After bootloading all DSPs, start DSP0 running
1542 * The DSP0 code will handle starting and synchronizing with its slaves
1543 */
1544 if (phw->p_interface_buffer) {
1545 /* we need to tell the card the physical PCI address */
1546 u32 physicalPC_iaddress;
1547 struct bus_master_interface *interface =
1548 phw->p_interface_buffer;
1549 u32 host_mailbox_address_on_dsp;
1550 u32 physicalPC_iaddress_verify = 0;
1551 int time_out = 10;
1552 /* set ack so we know when DSP is ready to go */
1553 /* (dwDspAck will be changed to HIF_RESET) */
1554 interface->dsp_ack = H620_HIF_UNKNOWN;
1555 wmb(); /* ensure ack is written before dsp writes back */
1556
1557 err = hpios_locked_mem_get_phys_addr(&phw->h_locked_mem,
1558 &physicalPC_iaddress);
1559
1560 /* locate the host mailbox on the DSP. */
1561 host_mailbox_address_on_dsp = 0x80000000;
1562 while ((physicalPC_iaddress != physicalPC_iaddress_verify)
1563 && time_out--) {
1564 err = boot_loader_write_mem32(pao, 0,
1565 host_mailbox_address_on_dsp,
1566 physicalPC_iaddress);
1567 physicalPC_iaddress_verify =
1568 boot_loader_read_mem32(pao, 0,
1569 host_mailbox_address_on_dsp);
1570 }
1571 }
1572 HPI_DEBUG_LOG(DEBUG, "starting DS_ps running\n");
1573 /* enable interrupts */
1574 temp = ioread32(phw->prHSR);
1575 temp &= ~(u32)C6205_HSR_INTAM;
1576 iowrite32(temp, phw->prHSR);
1577
1578 /* start code running... */
1579 temp = ioread32(phw->prHDCR);
1580 temp |= (u32)C6205_HDCR_DSPINT;
1581 iowrite32(temp, phw->prHDCR);
1582
1583 /* give the DSP 10ms to start up */
1584 hpios_delay_micro_seconds(10000);
1585 return err;
1586
1587}
1588
1589/*****************************************************************************/
1590/* Bootloader utility functions */
1591
1592static u32 boot_loader_read_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1593 u32 address)
1594{
1595 struct hpi_hw_obj *phw = pao->priv;
1596 u32 data = 0;
1597 __iomem u32 *p_data;
1598
1599 if (dsp_index == 0) {
1600 /* DSP 0 is always C6205 */
1601 if ((address >= 0x01800000) & (address < 0x02000000)) {
1602 /* BAR1 register access */
1603 p_data = pao->pci.ap_mem_base[1] +
1604 (address & 0x007fffff) /
1605 sizeof(*pao->pci.ap_mem_base[1]);
1606 /* HPI_DEBUG_LOG(WARNING,
1607 "BAR1 access %08x\n", dwAddress); */
1608 } else {
1609 u32 dw4M_page = address >> 22L;
1610 if (dw4M_page != phw->dsp_page) {
1611 phw->dsp_page = dw4M_page;
1612 /* *INDENT OFF* */
1613 iowrite32(phw->dsp_page, phw->prDSPP);
1614 /* *INDENT-ON* */
1615 }
1616 address &= 0x3fffff; /* address within 4M page */
1617 /* BAR0 memory access */
1618 p_data = pao->pci.ap_mem_base[0] +
1619 address / sizeof(u32);
1620 }
1621 data = ioread32(p_data);
1622 } else if (dsp_index == 1) {
1623 /* DSP 1 is a C6713 */
1624 u32 lsb;
1625 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1626 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1627 lsb = boot_loader_read_mem32(pao, 0, HPIDL_ADDR);
1628 data = boot_loader_read_mem32(pao, 0, HPIDH_ADDR);
1629 data = (data << 16) | (lsb & 0xFFFF);
1630 }
1631 return data;
1632}
1633
1634static u16 boot_loader_write_mem32(struct hpi_adapter_obj *pao, int dsp_index,
1635 u32 address, u32 data)
1636{
1637 struct hpi_hw_obj *phw = pao->priv;
1638 u16 err = 0;
1639 __iomem u32 *p_data;
1640 /* u32 dwVerifyData=0; */
1641
1642 if (dsp_index == 0) {
1643 /* DSP 0 is always C6205 */
1644 if ((address >= 0x01800000) & (address < 0x02000000)) {
1645 /* BAR1 - DSP register access using */
1646 /* Non-prefetchable PCI access */
1647 p_data = pao->pci.ap_mem_base[1] +
1648 (address & 0x007fffff) /
1649 sizeof(*pao->pci.ap_mem_base[1]);
1650 } else {
1651 /* BAR0 access - all of DSP memory using */
1652 /* pre-fetchable PCI access */
1653 u32 dw4M_page = address >> 22L;
1654 if (dw4M_page != phw->dsp_page) {
1655 phw->dsp_page = dw4M_page;
1656 /* *INDENT-OFF* */
1657 iowrite32(phw->dsp_page, phw->prDSPP);
1658 /* *INDENT-ON* */
1659 }
1660 address &= 0x3fffff; /* address within 4M page */
1661 p_data = pao->pci.ap_mem_base[0] +
1662 address / sizeof(u32);
1663 }
1664 iowrite32(data, p_data);
1665 } else if (dsp_index == 1) {
1666 /* DSP 1 is a C6713 */
1667 boot_loader_write_mem32(pao, 0, HPIAL_ADDR, address);
1668 boot_loader_write_mem32(pao, 0, HPIAH_ADDR, address >> 16);
1669
1670 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1671 boot_loader_read_mem32(pao, 0, 0);
1672
1673 boot_loader_write_mem32(pao, 0, HPIDL_ADDR, data);
1674 boot_loader_write_mem32(pao, 0, HPIDH_ADDR, data >> 16);
1675
1676 /* dummy read every 4 words for 6205 advisory 1.4.4 */
1677 boot_loader_read_mem32(pao, 0, 0);
1678 } else
1679 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1680 return err;
1681}
1682
1683static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index)
1684{
1685 u16 err = 0;
1686
1687 if (dsp_index == 0) {
1688 u32 setting;
1689
1690 /* DSP 0 is always C6205 */
1691
1692 /* Set the EMIF */
1693 /* memory map of C6205 */
1694 /* 00000000-0000FFFF 16Kx32 internal program */
1695 /* 00400000-00BFFFFF CE0 2Mx32 SDRAM running @ 100MHz */
1696
1697 /* EMIF config */
1698 /*------------ */
1699 /* Global EMIF control */
1700 boot_loader_write_mem32(pao, dsp_index, 0x01800000, 0x3779);
1701#define WS_OFS 28
1702#define WST_OFS 22
1703#define WH_OFS 20
1704#define RS_OFS 16
1705#define RST_OFS 8
1706#define MTYPE_OFS 4
1707#define RH_OFS 0
1708
1709 /* EMIF CE0 setup - 2Mx32 Sync DRAM on ASI5000 cards only */
1710 setting = 0x00000030;
1711 boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting);
1712 if (setting != boot_loader_read_mem32(pao, dsp_index,
1713 0x01800008))
1714 return hpi6205_error(dsp_index,
1715 HPI6205_ERROR_DSP_EMIF);
1716
1717 /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */
1718 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1719 /* plenty of wait states. See dsn8701.rtf, and 6713 errata. */
1720 /* WST should be 71, but 63 is max possible */
1721 setting =
1722 (1L << WS_OFS) | (63L << WST_OFS) | (1L << WH_OFS) |
1723 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1724 (2L << MTYPE_OFS);
1725 boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting);
1726 if (setting != boot_loader_read_mem32(pao, dsp_index,
1727 0x01800004))
1728 return hpi6205_error(dsp_index,
1729 HPI6205_ERROR_DSP_EMIF);
1730
1731 /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */
1732 /* which occupies D15..0. 6713 starts at 27MHz, so need */
1733 /* plenty of wait states */
1734 setting =
1735 (1L << WS_OFS) | (28L << WST_OFS) | (1L << WH_OFS) |
1736 (1L << RS_OFS) | (63L << RST_OFS) | (1L << RH_OFS) |
1737 (2L << MTYPE_OFS);
1738 boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting);
1739 if (setting != boot_loader_read_mem32(pao, dsp_index,
1740 0x01800010))
1741 return hpi6205_error(dsp_index,
1742 HPI6205_ERROR_DSP_EMIF);
1743
1744 /* EMIF CE3 setup - 32 bit async. */
1745 /* This is the PLD on the ASI5000 cards only */
1746 setting =
1747 (1L << WS_OFS) | (10L << WST_OFS) | (1L << WH_OFS) |
1748 (1L << RS_OFS) | (10L << RST_OFS) | (1L << RH_OFS) |
1749 (2L << MTYPE_OFS);
1750 boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting);
1751 if (setting != boot_loader_read_mem32(pao, dsp_index,
1752 0x01800014))
1753 return hpi6205_error(dsp_index,
1754 HPI6205_ERROR_DSP_EMIF);
1755
1756 /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */
1757 /* need to use this else DSP code crashes? */
1758 boot_loader_write_mem32(pao, dsp_index, 0x01800018,
1759 0x07117000);
1760
1761 /* EMIF SDRAM Refresh Timing */
1762 /* EMIF SDRAM timing (orig = 0x410, emulator = 0x61a) */
1763 boot_loader_write_mem32(pao, dsp_index, 0x0180001C,
1764 0x00000410);
1765
1766 } else if (dsp_index == 1) {
1767 /* test access to the C6713s HPI registers */
1768 u32 write_data = 0, read_data = 0, i = 0;
1769
1770 /* Set up HPIC for little endian, by setiing HPIC:HWOB=1 */
1771 write_data = 1;
1772 boot_loader_write_mem32(pao, 0, HPICL_ADDR, write_data);
1773 boot_loader_write_mem32(pao, 0, HPICH_ADDR, write_data);
1774 /* C67 HPI is on lower 16bits of 32bit EMIF */
1775 read_data =
1776 0xFFF7 & boot_loader_read_mem32(pao, 0, HPICL_ADDR);
1777 if (write_data != read_data) {
1778 err = hpi6205_error(dsp_index,
1779 HPI6205_ERROR_C6713_HPIC);
1780 HPI_DEBUG_LOG(ERROR, "HPICL %x %x\n", write_data,
1781 read_data);
1782
1783 return err;
1784 }
1785 /* HPIA - walking ones test */
1786 write_data = 1;
1787 for (i = 0; i < 32; i++) {
1788 boot_loader_write_mem32(pao, 0, HPIAL_ADDR,
1789 write_data);
1790 boot_loader_write_mem32(pao, 0, HPIAH_ADDR,
1791 (write_data >> 16));
1792 read_data =
1793 0xFFFF & boot_loader_read_mem32(pao, 0,
1794 HPIAL_ADDR);
1795 read_data =
1796 read_data | ((0xFFFF &
1797 boot_loader_read_mem32(pao, 0,
1798 HPIAH_ADDR))
1799 << 16);
1800 if (read_data != write_data) {
1801 err = hpi6205_error(dsp_index,
1802 HPI6205_ERROR_C6713_HPIA);
1803 HPI_DEBUG_LOG(ERROR, "HPIA %x %x\n",
1804 write_data, read_data);
1805 return err;
1806 }
1807 write_data = write_data << 1;
1808 }
1809
1810 /* setup C67x PLL
1811 * ** C6713 datasheet says we cannot program PLL from HPI,
1812 * and indeed if we try to set the PLL multiply from the HPI,
1813 * the PLL does not seem to lock, so we enable the PLL and
1814 * use the default multiply of x 7, which for a 27MHz clock
1815 * gives a DSP speed of 189MHz
1816 */
1817 /* bypass PLL */
1818 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0000);
1819 hpios_delay_micro_seconds(1000);
1820 /* EMIF = 189/3=63MHz */
1821 boot_loader_write_mem32(pao, dsp_index, 0x01B7C120, 0x8002);
1822 /* peri = 189/2 */
1823 boot_loader_write_mem32(pao, dsp_index, 0x01B7C11C, 0x8001);
1824 /* cpu = 189/1 */
1825 boot_loader_write_mem32(pao, dsp_index, 0x01B7C118, 0x8000);
1826 hpios_delay_micro_seconds(1000);
1827 /* ** SGT test to take GPO3 high when we start the PLL */
1828 /* and low when the delay is completed */
1829 /* FSX0 <- '1' (GPO3) */
1830 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A0A);
1831 /* PLL not bypassed */
1832 boot_loader_write_mem32(pao, dsp_index, 0x01B7C100, 0x0001);
1833 hpios_delay_micro_seconds(1000);
1834 /* FSX0 <- '0' (GPO3) */
1835 boot_loader_write_mem32(pao, 0, (0x018C0024L), 0x00002A02);
1836
1837 /* 6205 EMIF CE1 resetup - 32 bit async. */
1838 /* Now 6713 #1 is running at 189MHz can reduce waitstates */
1839 boot_loader_write_mem32(pao, 0, 0x01800004, /* CE1 */
1840 (1L << WS_OFS) | (8L << WST_OFS) | (1L << WH_OFS) |
1841 (1L << RS_OFS) | (12L << RST_OFS) | (1L << RH_OFS) |
1842 (2L << MTYPE_OFS));
1843
1844 hpios_delay_micro_seconds(1000);
1845
1846 /* check that we can read one of the PLL registers */
1847 /* PLL should not be bypassed! */
1848 if ((boot_loader_read_mem32(pao, dsp_index, 0x01B7C100) & 0xF)
1849 != 0x0001) {
1850 err = hpi6205_error(dsp_index,
1851 HPI6205_ERROR_C6713_PLL);
1852 return err;
1853 }
1854 /* setup C67x EMIF (note this is the only use of
1855 BAR1 via BootLoader_WriteMem32) */
1856 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_GCTL,
1857 0x000034A8);
1858 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_CE0,
1859 0x00000030);
1860 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMEXT,
1861 0x001BDF29);
1862 boot_loader_write_mem32(pao, dsp_index, C6713_EMIF_SDRAMCTL,
1863 0x47117000);
1864 boot_loader_write_mem32(pao, dsp_index,
1865 C6713_EMIF_SDRAMTIMING, 0x00000410);
1866
1867 hpios_delay_micro_seconds(1000);
1868 } else if (dsp_index == 2) {
1869 /* DSP 2 is a C6713 */
1870
1871 } else
1872 err = hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1873 return err;
1874}
1875
1876static u16 boot_loader_test_memory(struct hpi_adapter_obj *pao, int dsp_index,
1877 u32 start_address, u32 length)
1878{
1879 u32 i = 0, j = 0;
1880 u32 test_addr = 0;
1881 u32 test_data = 0, data = 0;
1882
1883 length = 1000;
1884
1885 /* for 1st word, test each bit in the 32bit word, */
1886 /* dwLength specifies number of 32bit words to test */
1887 /*for(i=0; i<dwLength; i++) */
1888 i = 0;
1889 {
1890 test_addr = start_address + i * 4;
1891 test_data = 0x00000001;
1892 for (j = 0; j < 32; j++) {
1893 boot_loader_write_mem32(pao, dsp_index, test_addr,
1894 test_data);
1895 data = boot_loader_read_mem32(pao, dsp_index,
1896 test_addr);
1897 if (data != test_data) {
1898 HPI_DEBUG_LOG(VERBOSE,
1899 "memtest error details "
1900 "%08x %08x %08x %i\n", test_addr,
1901 test_data, data, dsp_index);
1902 return 1; /* error */
1903 }
1904 test_data = test_data << 1;
1905 } /* for(j) */
1906 } /* for(i) */
1907
1908 /* for the next 100 locations test each location, leaving it as zero */
1909 /* write a zero to the next word in memory before we read */
1910 /* the previous write to make sure every memory location is unique */
1911 for (i = 0; i < 100; i++) {
1912 test_addr = start_address + i * 4;
1913 test_data = 0xA5A55A5A;
1914 boot_loader_write_mem32(pao, dsp_index, test_addr, test_data);
1915 boot_loader_write_mem32(pao, dsp_index, test_addr + 4, 0);
1916 data = boot_loader_read_mem32(pao, dsp_index, test_addr);
1917 if (data != test_data) {
1918 HPI_DEBUG_LOG(VERBOSE,
1919 "memtest error details "
1920 "%08x %08x %08x %i\n", test_addr, test_data,
1921 data, dsp_index);
1922 return 1; /* error */
1923 }
1924 /* leave location as zero */
1925 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1926 }
1927
1928 /* zero out entire memory block */
1929 for (i = 0; i < length; i++) {
1930 test_addr = start_address + i * 4;
1931 boot_loader_write_mem32(pao, dsp_index, test_addr, 0x0);
1932 }
1933 return 0;
1934}
1935
1936static u16 boot_loader_test_internal_memory(struct hpi_adapter_obj *pao,
1937 int dsp_index)
1938{
1939 int err = 0;
1940 if (dsp_index == 0) {
1941 /* DSP 0 is a C6205 */
1942 /* 64K prog mem */
1943 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1944 0x10000);
1945 if (!err)
1946 /* 64K data mem */
1947 err = boot_loader_test_memory(pao, dsp_index,
1948 0x80000000, 0x10000);
1949 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1950 /* DSP 1&2 are a C6713 */
1951 /* 192K internal mem */
1952 err = boot_loader_test_memory(pao, dsp_index, 0x00000000,
1953 0x30000);
1954 if (!err)
1955 /* 64K internal mem / L2 cache */
1956 err = boot_loader_test_memory(pao, dsp_index,
1957 0x00030000, 0x10000);
1958 } else
1959 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1960
1961 if (err)
1962 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_INTMEM);
1963 else
1964 return 0;
1965}
1966
1967static u16 boot_loader_test_external_memory(struct hpi_adapter_obj *pao,
1968 int dsp_index)
1969{
1970 u32 dRAM_start_address = 0;
1971 u32 dRAM_size = 0;
1972
1973 if (dsp_index == 0) {
1974 /* only test for SDRAM if an ASI5000 card */
1975 if (pao->pci.subsys_device_id == 0x5000) {
1976 /* DSP 0 is always C6205 */
1977 dRAM_start_address = 0x00400000;
1978 dRAM_size = 0x200000;
1979 /*dwDRAMinc=1024; */
1980 } else
1981 return 0;
1982 } else if ((dsp_index == 1) || (dsp_index == 2)) {
1983 /* DSP 1 is a C6713 */
1984 dRAM_start_address = 0x80000000;
1985 dRAM_size = 0x200000;
1986 /*dwDRAMinc=1024; */
1987 } else
1988 return hpi6205_error(dsp_index, HPI6205_ERROR_BAD_DSPINDEX);
1989
1990 if (boot_loader_test_memory(pao, dsp_index, dRAM_start_address,
1991 dRAM_size))
1992 return hpi6205_error(dsp_index, HPI6205_ERROR_DSP_EXTMEM);
1993 return 0;
1994}
1995
1996static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index)
1997{
1998 u32 data = 0;
1999 if (dsp_index == 0) {
2000 /* only test for DSP0 PLD on ASI5000 card */
2001 if (pao->pci.subsys_device_id == 0x5000) {
2002 /* PLD is located at CE3=0x03000000 */
2003 data = boot_loader_read_mem32(pao, dsp_index,
2004 0x03000008);
2005 if ((data & 0xF) != 0x5)
2006 return hpi6205_error(dsp_index,
2007 HPI6205_ERROR_DSP_PLD);
2008 data = boot_loader_read_mem32(pao, dsp_index,
2009 0x0300000C);
2010 if ((data & 0xF) != 0xA)
2011 return hpi6205_error(dsp_index,
2012 HPI6205_ERROR_DSP_PLD);
2013 }
2014 } else if (dsp_index == 1) {
2015 /* DSP 1 is a C6713 */
2016 if (pao->pci.subsys_device_id == 0x8700) {
2017 /* PLD is located at CE1=0x90000000 */
2018 data = boot_loader_read_mem32(pao, dsp_index,
2019 0x90000010);
2020 if ((data & 0xFF) != 0xAA)
2021 return hpi6205_error(dsp_index,
2022 HPI6205_ERROR_DSP_PLD);
2023 /* 8713 - LED on */
2024 boot_loader_write_mem32(pao, dsp_index, 0x90000000,
2025 0x02);
2026 }
2027 }
2028 return 0;
2029}
2030
2031/** Transfer data to or from DSP
2032 nOperation = H620_H620_HIF_SEND_DATA or H620_HIF_GET_DATA
2033*/
2034static short hpi6205_transfer_data(struct hpi_adapter_obj *pao, u8 *p_data,
2035 u32 data_size, int operation)
2036{
2037 struct hpi_hw_obj *phw = pao->priv;
2038 u32 data_transferred = 0;
2039 u16 err = 0;
2040#ifndef HPI6205_NO_HSR_POLL
2041 u32 time_out;
2042#endif
2043 u32 temp2;
2044 struct bus_master_interface *interface = phw->p_interface_buffer;
2045
2046 if (!p_data)
2047 return HPI_ERROR_INVALID_DATA_TRANSFER;
2048
2049 data_size &= ~3L; /* round data_size down to nearest 4 bytes */
2050
2051 /* make sure state is IDLE */
2052 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT))
2053 return HPI_ERROR_DSP_HARDWARE;
2054
2055 while (data_transferred < data_size) {
2056 u32 this_copy = data_size - data_transferred;
2057
2058 if (this_copy > HPI6205_SIZEOF_DATA)
2059 this_copy = HPI6205_SIZEOF_DATA;
2060
2061 if (operation == H620_HIF_SEND_DATA)
2062 memcpy((void *)&interface->u.b_data[0],
2063 &p_data[data_transferred], this_copy);
2064
2065 interface->transfer_size_in_bytes = this_copy;
2066
2067#ifdef HPI6205_NO_HSR_POLL
2068 /* DSP must change this back to nOperation */
2069 interface->dsp_ack = H620_HIF_IDLE;
2070#endif
2071
2072 send_dsp_command(phw, operation);
2073
2074#ifdef HPI6205_NO_HSR_POLL
2075 temp2 = wait_dsp_ack(phw, operation, HPI6205_TIMEOUT);
2076 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2077 HPI6205_TIMEOUT - temp2, this_copy);
2078
2079 if (!temp2) {
2080 /* timed out */
2081 HPI_DEBUG_LOG(ERROR,
2082 "timed out waiting for " "state %d got %d\n",
2083 operation, interface->dsp_ack);
2084
2085 break;
2086 }
2087#else
2088 /* spin waiting on the result */
2089 time_out = HPI6205_TIMEOUT;
2090 temp2 = 0;
2091 while ((temp2 == 0) && time_out--) {
2092 /* give 16k bus mastering transfer time to happen */
2093 /*(16k / 132Mbytes/s = 122usec) */
2094 hpios_delay_micro_seconds(20);
2095 temp2 = ioread32(phw->prHSR);
2096 temp2 &= C6205_HSR_INTSRC;
2097 }
2098 HPI_DEBUG_LOG(DEBUG, "spun %d times for data xfer of %d\n",
2099 HPI6205_TIMEOUT - time_out, this_copy);
2100 if (temp2 == C6205_HSR_INTSRC) {
2101 HPI_DEBUG_LOG(VERBOSE,
2102 "interrupt from HIF <data> OK\n");
2103 /*
2104 if(interface->dwDspAck != nOperation) {
2105 HPI_DEBUG_LOG(DEBUG("interface->dwDspAck=%d,
2106 expected %d \n",
2107 interface->dwDspAck,nOperation);
2108 }
2109 */
2110 }
2111/* need to handle this differently... */
2112 else {
2113 HPI_DEBUG_LOG(ERROR,
2114 "interrupt from HIF <data> BAD\n");
2115 err = HPI_ERROR_DSP_HARDWARE;
2116 }
2117
2118 /* reset the interrupt from the DSP */
2119 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2120#endif
2121 if (operation == H620_HIF_GET_DATA)
2122 memcpy(&p_data[data_transferred],
2123 (void *)&interface->u.b_data[0], this_copy);
2124
2125 data_transferred += this_copy;
2126 }
2127 if (interface->dsp_ack != operation)
2128 HPI_DEBUG_LOG(DEBUG, "interface->dsp_ack=%d, expected %d\n",
2129 interface->dsp_ack, operation);
2130 /* err=HPI_ERROR_DSP_HARDWARE; */
2131
2132 send_dsp_command(phw, H620_HIF_IDLE);
2133
2134 return err;
2135}
2136
2137/* wait for up to timeout_us microseconds for the DSP
2138 to signal state by DMA into dwDspAck
2139*/
2140static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us)
2141{
2142 struct bus_master_interface *interface = phw->p_interface_buffer;
2143 int t = timeout_us / 4;
2144
2145 rmb(); /* ensure interface->dsp_ack is up to date */
2146 while ((interface->dsp_ack != state) && --t) {
2147 hpios_delay_micro_seconds(4);
2148 rmb(); /* DSP changes dsp_ack by DMA */
2149 }
2150
2151 /*HPI_DEBUG_LOG(VERBOSE, "Spun %d for %d\n", timeout_us/4-t, state); */
2152 return t * 4;
2153}
2154
2155/* set the busmaster interface to cmd, then interrupt the DSP */
2156static void send_dsp_command(struct hpi_hw_obj *phw, int cmd)
2157{
2158 struct bus_master_interface *interface = phw->p_interface_buffer;
2159
2160 u32 r;
2161
2162 interface->host_cmd = cmd;
2163 wmb(); /* DSP gets state by DMA, make sure it is written to memory */
2164 /* before we interrupt the DSP */
2165 r = ioread32(phw->prHDCR);
2166 r |= (u32)C6205_HDCR_DSPINT;
2167 iowrite32(r, phw->prHDCR);
2168 r &= ~(u32)C6205_HDCR_DSPINT;
2169 iowrite32(r, phw->prHDCR);
2170}
2171
2172static unsigned int message_count;
2173
2174static u16 message_response_sequence(struct hpi_adapter_obj *pao,
2175 struct hpi_message *phm, struct hpi_response *phr)
2176{
2177#ifndef HPI6205_NO_HSR_POLL
2178 u32 temp2;
2179#endif
2180 u32 time_out, time_out2;
2181 struct hpi_hw_obj *phw = pao->priv;
2182 struct bus_master_interface *interface = phw->p_interface_buffer;
2183 u16 err = 0;
2184
2185 message_count++;
2186 /* Assume buffer of type struct bus_master_interface
2187 is allocated "noncacheable" */
2188
2189 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2190 HPI_DEBUG_LOG(DEBUG, "timeout waiting for idle\n");
2191 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2192 }
2193 interface->u.message_buffer = *phm;
2194 /* signal we want a response */
2195 send_dsp_command(phw, H620_HIF_GET_RESP);
2196
2197 time_out2 = wait_dsp_ack(phw, H620_HIF_GET_RESP, HPI6205_TIMEOUT);
2198
2199 if (time_out2 == 0) {
2200 HPI_DEBUG_LOG(ERROR,
2201 "(%u) timed out waiting for " "GET_RESP state [%x]\n",
2202 message_count, interface->dsp_ack);
2203 } else {
2204 HPI_DEBUG_LOG(VERBOSE,
2205 "(%u) transition to GET_RESP after %u\n",
2206 message_count, HPI6205_TIMEOUT - time_out2);
2207 }
2208 /* spin waiting on HIF interrupt flag (end of msg process) */
2209 time_out = HPI6205_TIMEOUT;
2210
2211#ifndef HPI6205_NO_HSR_POLL
2212 temp2 = 0;
2213 while ((temp2 == 0) && --time_out) {
2214 temp2 = ioread32(phw->prHSR);
2215 temp2 &= C6205_HSR_INTSRC;
2216 hpios_delay_micro_seconds(1);
2217 }
2218 if (temp2 == C6205_HSR_INTSRC) {
2219 rmb(); /* ensure we see latest value for dsp_ack */
2220 if ((interface->dsp_ack != H620_HIF_GET_RESP)) {
2221 HPI_DEBUG_LOG(DEBUG,
2222 "(%u)interface->dsp_ack(0x%x) != "
2223 "H620_HIF_GET_RESP, t=%u\n", message_count,
2224 interface->dsp_ack,
2225 HPI6205_TIMEOUT - time_out);
2226 } else {
2227 HPI_DEBUG_LOG(VERBOSE,
2228 "(%u)int with GET_RESP after %u\n",
2229 message_count, HPI6205_TIMEOUT - time_out);
2230 }
2231
2232 } else {
2233 /* can we do anything else in response to the error ? */
2234 HPI_DEBUG_LOG(ERROR,
2235 "interrupt from HIF module BAD (function %x)\n",
2236 phm->function);
2237 }
2238
2239 /* reset the interrupt from the DSP */
2240 iowrite32(C6205_HSR_INTSRC, phw->prHSR);
2241#endif
2242
2243 /* read the result */
2244 if (time_out != 0)
2245 *phr = interface->u.response_buffer;
2246
2247 /* set interface back to idle */
2248 send_dsp_command(phw, H620_HIF_IDLE);
2249
2250 if ((time_out == 0) || (time_out2 == 0)) {
2251 HPI_DEBUG_LOG(DEBUG, "something timed out!\n");
2252 return hpi6205_error(0, HPI6205_ERROR_MSG_RESP_TIMEOUT);
2253 }
2254 /* special case for adapter close - */
2255 /* wait for the DSP to indicate it is idle */
2256 if (phm->function == HPI_ADAPTER_CLOSE) {
2257 if (!wait_dsp_ack(phw, H620_HIF_IDLE, HPI6205_TIMEOUT)) {
2258 HPI_DEBUG_LOG(DEBUG,
2259 "timeout waiting for idle "
2260 "(on adapter_close)\n");
2261 return hpi6205_error(0,
2262 HPI6205_ERROR_MSG_RESP_IDLE_TIMEOUT);
2263 }
2264 }
2265 err = hpi_validate_response(phm, phr);
2266 return err;
2267}
2268
2269static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
2270 struct hpi_response *phr)
2271{
2272
2273 u16 err = 0;
2274
2275 hpios_dsplock_lock(pao);
2276
2277 err = message_response_sequence(pao, phm, phr);
2278
2279 /* maybe an error response */
2280 if (err) {
2281 /* something failed in the HPI/DSP interface */
2282 phr->error = err;
2283 pao->dsp_crashed++;
2284
2285 /* just the header of the response is valid */
2286 phr->size = sizeof(struct hpi_response_header);
2287 goto err;
2288 } else
2289 pao->dsp_crashed = 0;
2290
2291 if (phr->error != 0) /* something failed in the DSP */
2292 goto err;
2293
2294 switch (phm->function) {
2295 case HPI_OSTREAM_WRITE:
2296 case HPI_ISTREAM_ANC_WRITE:
2297 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2298 phm->u.d.u.data.data_size, H620_HIF_SEND_DATA);
2299 break;
2300
2301 case HPI_ISTREAM_READ:
2302 case HPI_OSTREAM_ANC_READ:
2303 err = hpi6205_transfer_data(pao, phm->u.d.u.data.pb_data,
2304 phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
2305 break;
2306
2307 case HPI_CONTROL_SET_STATE:
2308 if (phm->object == HPI_OBJ_CONTROLEX
2309 && phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
2310 err = hpi6205_transfer_data(pao,
2311 phm->u.cx.u.cobranet_bigdata.pb_data,
2312 phm->u.cx.u.cobranet_bigdata.byte_count,
2313 H620_HIF_SEND_DATA);
2314 break;
2315
2316 case HPI_CONTROL_GET_STATE:
2317 if (phm->object == HPI_OBJ_CONTROLEX
2318 && phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
2319 err = hpi6205_transfer_data(pao,
2320 phm->u.cx.u.cobranet_bigdata.pb_data,
2321 phr->u.cx.u.cobranet_data.byte_count,
2322 H620_HIF_GET_DATA);
2323 break;
2324 }
2325 phr->error = err;
2326
2327err:
2328 hpios_dsplock_unlock(pao);
2329
2330 return;
2331}
diff --git a/sound/pci/asihpi/hpi6205.h b/sound/pci/asihpi/hpi6205.h
new file mode 100644
index 000000000000..1adae0857cda
--- /dev/null
+++ b/sound/pci/asihpi/hpi6205.h
@@ -0,0 +1,93 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Host Interface module for an ASI6205 based
20bus mastering PCI adapter.
21
22Copyright AudioScience, Inc., 2003
23******************************************************************************/
24
25#ifndef _HPI6205_H_
26#define _HPI6205_H_
27
28/* transitional conditional compile shared between host and DSP */
29/* #define HPI6205_NO_HSR_POLL */
30
31#include "hpi_internal.h"
32
33/***********************************************************
34 Defines used for basic messaging
35************************************************************/
36#define H620_HIF_RESET 0
37#define H620_HIF_IDLE 1
38#define H620_HIF_GET_RESP 2
39#define H620_HIF_DATA_DONE 3
40#define H620_HIF_DATA_MASK 0x10
41#define H620_HIF_SEND_DATA 0x14
42#define H620_HIF_GET_DATA 0x15
43#define H620_HIF_UNKNOWN 0x0000ffff
44
45/***********************************************************
46 Types used for mixer control caching
47************************************************************/
48
49#define H620_MAX_ISTREAMS 32
50#define H620_MAX_OSTREAMS 32
51#define HPI_NMIXER_CONTROLS 2048
52
53/*********************************************************************
54This is used for dynamic control cache allocation
55**********************************************************************/
56struct controlcache_6205 {
57 u32 number_of_controls;
58 u32 physical_address32;
59 u32 size_in_bytes;
60};
61
62/*********************************************************************
63This is used for dynamic allocation of async event array
64**********************************************************************/
65struct async_event_buffer_6205 {
66 u32 physical_address32;
67 u32 spare;
68 struct hpi_fifo_buffer b;
69};
70
71/***********************************************************
72The Host located memory buffer that the 6205 will bus master
73in and out of.
74************************************************************/
75#define HPI6205_SIZEOF_DATA (16*1024)
76struct bus_master_interface {
77 u32 host_cmd;
78 u32 dsp_ack;
79 u32 transfer_size_in_bytes;
80 union {
81 struct hpi_message message_buffer;
82 struct hpi_response response_buffer;
83 u8 b_data[HPI6205_SIZEOF_DATA];
84 } u;
85 struct controlcache_6205 control_cache;
86 struct async_event_buffer_6205 async_buffer;
87 struct hpi_hostbuffer_status
88 instream_host_buffer_status[H620_MAX_ISTREAMS];
89 struct hpi_hostbuffer_status
90 outstream_host_buffer_status[H620_MAX_OSTREAMS];
91};
92
93#endif
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h
new file mode 100644
index 000000000000..f1cd6f1a0d44
--- /dev/null
+++ b/sound/pci/asihpi/hpi_internal.h
@@ -0,0 +1,1641 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI internal definitions
20
21(C) Copyright AudioScience Inc. 1996-2009
22******************************************************************************/
23
24#ifndef _HPI_INTERNAL_H_
25#define _HPI_INTERNAL_H_
26
27#include "hpi.h"
28/** maximum number of memory regions mapped to an adapter */
29#define HPI_MAX_ADAPTER_MEM_SPACES (2)
30
31/* Each OS needs its own hpios.h, or specific define as above */
32#include "hpios.h"
33
34/* physical memory allocation */
35void hpios_locked_mem_init(void
36 );
37void hpios_locked_mem_free_all(void
38 );
39#define hpios_locked_mem_prepare(a, b, c, d);
40#define hpios_locked_mem_unprepare(a)
41
42/** Allocate and map an area of locked memory for bus master DMA operations.
43
44On success, *pLockedMemeHandle is a valid handle, and 0 is returned
45On error *pLockedMemHandle marked invalid, non-zero returned.
46
47If this function succeeds, then HpiOs_LockedMem_GetVirtAddr() and
48HpiOs_LockedMem_GetPyhsAddr() will always succed on the returned handle.
49*/
50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_locked_mem_handle,
51 /**< memory handle */
52 u32 size, /**< size in bytes to allocate */
53 struct pci_dev *p_os_reference
54 /**< OS specific data required for memory allocation */
55 );
56
57/** Free mapping and memory represented by LockedMemHandle
58
59Frees any resources, then invalidates the handle.
60Returns 0 on success, 1 if handle is invalid.
61
62*/
63u16 hpios_locked_mem_free(struct consistent_dma_area *locked_mem_handle);
64
65/** Get the physical PCI address of memory represented by LockedMemHandle.
66
67If handle is invalid *pPhysicalAddr is set to zero and return 1
68*/
69u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
70 *locked_mem_handle, u32 *p_physical_addr);
71
72/** Get the CPU address of of memory represented by LockedMemHandle.
73
74If handle is NULL *ppvVirtualAddr is set to NULL and return 1
75*/
76u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
77 *locked_mem_handle, void **ppv_virtual_addr);
78
79/** Check that handle is valid
80i.e it represents a valid memory area
81*/
82u16 hpios_locked_mem_valid(struct consistent_dma_area *locked_mem_handle);
83
84/* timing/delay */
85void hpios_delay_micro_seconds(u32 num_micro_sec);
86
87struct hpi_message;
88struct hpi_response;
89
90typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *);
91
92/* If the assert fails, compiler complains
93 something like size of array `msg' is negative.
94 Unlike linux BUILD_BUG_ON, this works outside function scope.
95*/
96#define compile_time_assert(cond, msg) \
97 typedef char ASSERT_##msg[(cond) ? 1 : -1]
98
99/*/////////////////////////////////////////////////////////////////////////// */
100/* Private HPI Entity related definitions */
101
102#define STR_SIZE_FIELD_MAX 65535U
103#define STR_TYPE_FIELD_MAX 255U
104#define STR_ROLE_FIELD_MAX 255U
105
106struct hpi_entity_str {
107 uint16_t size;
108 uint8_t type;
109 uint8_t role;
110};
111
112#if defined(_MSC_VER)
113#pragma warning(push)
114#pragma warning(disable : 4200)
115#endif
116
117struct hpi_entity {
118 struct hpi_entity_str header;
119#if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008))
120 /* DSP C6000 compiler v6.0.8 and lower
121 do not support flexible array member */
122 uint8_t value[];
123#else
124 /* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */
125#define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE
126 uint8_t value[1];
127#endif
128};
129
130#if defined(_MSC_VER)
131#pragma warning(pop)
132#endif
133
134/******************************************* bus types */
135enum HPI_BUSES {
136 HPI_BUS_ISAPNP = 1,
137 HPI_BUS_PCI = 2,
138 HPI_BUS_USB = 3,
139 HPI_BUS_NET = 4
140};
141
142/******************************************* CONTROL ATTRIBUTES ****/
143/* (in order of control type ID */
144
145 /* This allows for 255 control types, 256 unique attributes each */
146#define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai)
147
148/* Get the sub-index of the attribute for a control type */
149#define HPI_CTL_ATTR_INDEX(i) (i&0xff)
150
151/* Generic control attributes. */
152
153/** Enable a control.
1540=disable, 1=enable
155\note generic to all mixer plugins?
156*/
157#define HPI_GENERIC_ENABLE HPI_CTL_ATTR(GENERIC, 1)
158
159/** Enable event generation for a control.
1600=disable, 1=enable
161\note generic to all controls that can generate events
162*/
163#define HPI_GENERIC_EVENT_ENABLE HPI_CTL_ATTR(GENERIC, 2)
164
165/* Volume Control attributes */
166#define HPI_VOLUME_GAIN HPI_CTL_ATTR(VOLUME, 1)
167#define HPI_VOLUME_AUTOFADE HPI_CTL_ATTR(VOLUME, 2)
168
169/** For HPI_ControlQuery() to get the number of channels of a volume control*/
170#define HPI_VOLUME_NUM_CHANNELS HPI_CTL_ATTR(VOLUME, 6)
171#define HPI_VOLUME_RANGE HPI_CTL_ATTR(VOLUME, 10)
172
173/** Level Control attributes */
174#define HPI_LEVEL_GAIN HPI_CTL_ATTR(LEVEL, 1)
175#define HPI_LEVEL_RANGE HPI_CTL_ATTR(LEVEL, 10)
176
177/* Meter Control attributes */
178/** return RMS signal level */
179#define HPI_METER_RMS HPI_CTL_ATTR(METER, 1)
180/** return peak signal level */
181#define HPI_METER_PEAK HPI_CTL_ATTR(METER, 2)
182/** ballistics for ALL rms meters on adapter */
183#define HPI_METER_RMS_BALLISTICS HPI_CTL_ATTR(METER, 3)
184/** ballistics for ALL peak meters on adapter */
185#define HPI_METER_PEAK_BALLISTICS HPI_CTL_ATTR(METER, 4)
186
187/** For HPI_ControlQuery() to get the number of channels of a meter control*/
188#define HPI_METER_NUM_CHANNELS HPI_CTL_ATTR(METER, 5)
189
190/* Multiplexer control attributes */
191#define HPI_MULTIPLEXER_SOURCE HPI_CTL_ATTR(MULTIPLEXER, 1)
192#define HPI_MULTIPLEXER_QUERYSOURCE HPI_CTL_ATTR(MULTIPLEXER, 2)
193
194/** AES/EBU transmitter control attributes */
195/** AESEBU or SPDIF */
196#define HPI_AESEBUTX_FORMAT HPI_CTL_ATTR(AESEBUTX, 1)
197#define HPI_AESEBUTX_SAMPLERATE HPI_CTL_ATTR(AESEBUTX, 3)
198#define HPI_AESEBUTX_CHANNELSTATUS HPI_CTL_ATTR(AESEBUTX, 4)
199#define HPI_AESEBUTX_USERDATA HPI_CTL_ATTR(AESEBUTX, 5)
200
201/** AES/EBU receiver control attributes */
202#define HPI_AESEBURX_FORMAT HPI_CTL_ATTR(AESEBURX, 1)
203#define HPI_AESEBURX_ERRORSTATUS HPI_CTL_ATTR(AESEBURX, 2)
204#define HPI_AESEBURX_SAMPLERATE HPI_CTL_ATTR(AESEBURX, 3)
205#define HPI_AESEBURX_CHANNELSTATUS HPI_CTL_ATTR(AESEBURX, 4)
206#define HPI_AESEBURX_USERDATA HPI_CTL_ATTR(AESEBURX, 5)
207
208/** \defgroup tuner_defs Tuners
209\{
210*/
211/** \defgroup tuner_attrs Tuner control attributes
212\{
213*/
214#define HPI_TUNER_BAND HPI_CTL_ATTR(TUNER, 1)
215#define HPI_TUNER_FREQ HPI_CTL_ATTR(TUNER, 2)
216#define HPI_TUNER_LEVEL HPI_CTL_ATTR(TUNER, 3)
217#define HPI_TUNER_AUDIOMUTE HPI_CTL_ATTR(TUNER, 4)
218/* use TUNER_STATUS instead */
219#define HPI_TUNER_VIDEO_STATUS HPI_CTL_ATTR(TUNER, 5)
220#define HPI_TUNER_GAIN HPI_CTL_ATTR(TUNER, 6)
221#define HPI_TUNER_STATUS HPI_CTL_ATTR(TUNER, 7)
222#define HPI_TUNER_MODE HPI_CTL_ATTR(TUNER, 8)
223/** RDS data. */
224#define HPI_TUNER_RDS HPI_CTL_ATTR(TUNER, 9)
225/** Audio pre-emphasis. */
226#define HPI_TUNER_DEEMPHASIS HPI_CTL_ATTR(TUNER, 10)
227/** HD Radio tuner program control. */
228#define HPI_TUNER_PROGRAM HPI_CTL_ATTR(TUNER, 11)
229/** HD Radio tuner digital signal quality. */
230#define HPI_TUNER_HDRADIO_SIGNAL_QUALITY HPI_CTL_ATTR(TUNER, 12)
231/** HD Radio SDK firmware version. */
232#define HPI_TUNER_HDRADIO_SDK_VERSION HPI_CTL_ATTR(TUNER, 13)
233/** HD Radio DSP firmware version. */
234#define HPI_TUNER_HDRADIO_DSP_VERSION HPI_CTL_ATTR(TUNER, 14)
235
236/** \} */
237
238/** \defgroup pads_attrs Tuner PADs control attributes
239\{
240*/
241/** The text string containing the station/channel combination. */
242#define HPI_PAD_CHANNEL_NAME HPI_CTL_ATTR(PAD, 1)
243/** The text string containing the artist. */
244#define HPI_PAD_ARTIST HPI_CTL_ATTR(PAD, 2)
245/** The text string containing the title. */
246#define HPI_PAD_TITLE HPI_CTL_ATTR(PAD, 3)
247/** The text string containing the comment. */
248#define HPI_PAD_COMMENT HPI_CTL_ATTR(PAD, 4)
249/** The integer containing the PTY code. */
250#define HPI_PAD_PROGRAM_TYPE HPI_CTL_ATTR(PAD, 5)
251/** The integer containing the program identification. */
252#define HPI_PAD_PROGRAM_ID HPI_CTL_ATTR(PAD, 6)
253/** The integer containing whether traffic information is supported.
254Contains either 1 or 0. */
255#define HPI_PAD_TA_SUPPORT HPI_CTL_ATTR(PAD, 7)
256/** The integer containing whether traffic announcement is in progress.
257Contains either 1 or 0. */
258#define HPI_PAD_TA_ACTIVE HPI_CTL_ATTR(PAD, 8)
259/** \} */
260/** \} */
261
262/* VOX control attributes */
263#define HPI_VOX_THRESHOLD HPI_CTL_ATTR(VOX, 1)
264
265/*?? channel mode used hpi_multiplexer_source attribute == 1 */
266#define HPI_CHANNEL_MODE_MODE HPI_CTL_ATTR(CHANNEL_MODE, 1)
267
268/** \defgroup channel_modes Channel Modes
269Used for HPI_ChannelModeSet/Get()
270\{
271*/
272/** Left channel out = left channel in, Right channel out = right channel in. */
273#define HPI_CHANNEL_MODE_NORMAL 1
274/** Left channel out = right channel in, Right channel out = left channel in. */
275#define HPI_CHANNEL_MODE_SWAP 2
276/** Left channel out = left channel in, Right channel out = left channel in. */
277#define HPI_CHANNEL_MODE_LEFT_TO_STEREO 3
278/** Left channel out = right channel in, Right channel out = right channel in.*/
279#define HPI_CHANNEL_MODE_RIGHT_TO_STEREO 4
280/** Left channel out = (left channel in + right channel in)/2,
281 Right channel out = mute. */
282#define HPI_CHANNEL_MODE_STEREO_TO_LEFT 5
283/** Left channel out = mute,
284 Right channel out = (right channel in + left channel in)/2. */
285#define HPI_CHANNEL_MODE_STEREO_TO_RIGHT 6
286#define HPI_CHANNEL_MODE_LAST 6
287/** \} */
288
289/* Bitstream control set attributes */
290#define HPI_BITSTREAM_DATA_POLARITY HPI_CTL_ATTR(BITSTREAM, 1)
291#define HPI_BITSTREAM_CLOCK_EDGE HPI_CTL_ATTR(BITSTREAM, 2)
292#define HPI_BITSTREAM_CLOCK_SOURCE HPI_CTL_ATTR(BITSTREAM, 3)
293
294#define HPI_POLARITY_POSITIVE 0
295#define HPI_POLARITY_NEGATIVE 1
296
297/* Bitstream control get attributes */
298#define HPI_BITSTREAM_ACTIVITY 1
299
300/* SampleClock control attributes */
301#define HPI_SAMPLECLOCK_SOURCE HPI_CTL_ATTR(SAMPLECLOCK, 1)
302#define HPI_SAMPLECLOCK_SAMPLERATE HPI_CTL_ATTR(SAMPLECLOCK, 2)
303#define HPI_SAMPLECLOCK_SOURCE_INDEX HPI_CTL_ATTR(SAMPLECLOCK, 3)
304#define HPI_SAMPLECLOCK_LOCAL_SAMPLERATE\
305 HPI_CTL_ATTR(SAMPLECLOCK, 4)
306#define HPI_SAMPLECLOCK_AUTO HPI_CTL_ATTR(SAMPLECLOCK, 5)
307#define HPI_SAMPLECLOCK_LOCAL_LOCK HPI_CTL_ATTR(SAMPLECLOCK, 6)
308
309/* Microphone control attributes */
310#define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1)
311
312/** Equalizer control attributes
313*/
314/** Used to get number of filters in an EQ. (Can't set) */
315#define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1)
316/** Set/get the filter by type, freq, Q, gain */
317#define HPI_EQUALIZER_FILTER HPI_CTL_ATTR(EQUALIZER, 2)
318/** Get the biquad coefficients */
319#define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3)
320
321#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1)
322
323/* Cobranet control attributes.
324 MUST be distinct from all other control attributes.
325 This is so that host side processing can easily identify a Cobranet control
326 and apply additional host side operations (like copying data) as required.
327*/
328#define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1)
329#define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2)
330#define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3)
331#define HPI_COBRANET_GET_DATA HPI_CTL_ATTR(COBRANET, 4)
332#define HPI_COBRANET_GET_STATUS HPI_CTL_ATTR(COBRANET, 5)
333#define HPI_COBRANET_SEND_PACKET HPI_CTL_ATTR(COBRANET, 6)
334#define HPI_COBRANET_GET_PACKET HPI_CTL_ATTR(COBRANET, 7)
335
336/*------------------------------------------------------------
337 Cobranet Chip Bridge - copied from HMI.H
338------------------------------------------------------------*/
339#define HPI_COBRANET_HMI_cobra_bridge 0x20000
340#define HPI_COBRANET_HMI_cobra_bridge_tx_pkt_buf \
341 (HPI_COBRANET_HMI_cobra_bridge + 0x1000)
342#define HPI_COBRANET_HMI_cobra_bridge_rx_pkt_buf \
343 (HPI_COBRANET_HMI_cobra_bridge + 0x2000)
344#define HPI_COBRANET_HMI_cobra_if_table1 0x110000
345#define HPI_COBRANET_HMI_cobra_if_phy_address \
346 (HPI_COBRANET_HMI_cobra_if_table1 + 0xd)
347#define HPI_COBRANET_HMI_cobra_protocolIP 0x72000
348#define HPI_COBRANET_HMI_cobra_ip_mon_currentIP \
349 (HPI_COBRANET_HMI_cobra_protocolIP + 0x0)
350#define HPI_COBRANET_HMI_cobra_ip_mon_staticIP \
351 (HPI_COBRANET_HMI_cobra_protocolIP + 0x2)
352#define HPI_COBRANET_HMI_cobra_sys 0x100000
353#define HPI_COBRANET_HMI_cobra_sys_desc \
354 (HPI_COBRANET_HMI_cobra_sys + 0x0)
355#define HPI_COBRANET_HMI_cobra_sys_objectID \
356 (HPI_COBRANET_HMI_cobra_sys + 0x100)
357#define HPI_COBRANET_HMI_cobra_sys_contact \
358 (HPI_COBRANET_HMI_cobra_sys + 0x200)
359#define HPI_COBRANET_HMI_cobra_sys_name \
360 (HPI_COBRANET_HMI_cobra_sys + 0x300)
361#define HPI_COBRANET_HMI_cobra_sys_location \
362 (HPI_COBRANET_HMI_cobra_sys + 0x400)
363
364/*------------------------------------------------------------
365 Cobranet Chip Status bits
366------------------------------------------------------------*/
367#define HPI_COBRANET_HMI_STATUS_RXPACKET 2
368#define HPI_COBRANET_HMI_STATUS_TXPACKET 3
369
370/*------------------------------------------------------------
371 Ethernet header size
372------------------------------------------------------------*/
373#define HPI_ETHERNET_HEADER_SIZE (16)
374
375/* These defines are used to fill in protocol information for an Ethernet packet
376 sent using HMI on CS18102 */
377/** ID supplied by Cirrius for ASI packets. */
378#define HPI_ETHERNET_PACKET_ID 0x85
379/** Simple packet - no special routing required */
380#define HPI_ETHERNET_PACKET_V1 0x01
381/** This packet must make its way to the host across the HPI interface */
382#define HPI_ETHERNET_PACKET_HOSTED_VIA_HMI 0x20
383/** This packet must make its way to the host across the HPI interface */
384#define HPI_ETHERNET_PACKET_HOSTED_VIA_HMI_V1 0x21
385/** This packet must make its way to the host across the HPI interface */
386#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI 0x40
387/** This packet must make its way to the host across the HPI interface */
388#define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
389
390#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */
391
392/** Base network time out is set to 100 milli-seconds. */
393#define HPI_ETHERNET_TIMEOUT_MS (100)
394
395/** \defgroup tonedet_attr Tonedetector attributes
396\{
397Used by HPI_ToneDetector_Set() and HPI_ToneDetector_Get()
398*/
399
400/** Set the threshold level of a tonedetector,
401Threshold is a -ve number in units of dB/100,
402*/
403#define HPI_TONEDETECTOR_THRESHOLD HPI_CTL_ATTR(TONEDETECTOR, 1)
404
405/** Get the current state of tonedetection
406The result is a bitmap of detected tones. pairs of bits represent the left
407and right channels, with left channel in LSB.
408The lowest frequency detector state is in the LSB
409*/
410#define HPI_TONEDETECTOR_STATE HPI_CTL_ATTR(TONEDETECTOR, 2)
411
412/** Get the frequency of a tonedetector band.
413*/
414#define HPI_TONEDETECTOR_FREQUENCY HPI_CTL_ATTR(TONEDETECTOR, 3)
415
416/**\}*/
417
418/** \defgroup silencedet_attr SilenceDetector attributes
419\{
420*/
421
422/** Get the current state of tonedetection
423The result is a bitmap with 1s for silent channels. Left channel is in LSB
424*/
425#define HPI_SILENCEDETECTOR_STATE \
426 HPI_CTL_ATTR(SILENCEDETECTOR, 2)
427
428/** Set the threshold level of a SilenceDetector,
429Threshold is a -ve number in units of dB/100,
430*/
431#define HPI_SILENCEDETECTOR_THRESHOLD \
432 HPI_CTL_ATTR(SILENCEDETECTOR, 1)
433
434/** get/set the silence time before the detector triggers
435*/
436#define HPI_SILENCEDETECTOR_DELAY \
437 HPI_CTL_ATTR(SILENCEDETECTOR, 3)
438
439/**\}*/
440
441/* Locked memory buffer alloc/free phases */
442/** use one message to allocate or free physical memory */
443#define HPI_BUFFER_CMD_EXTERNAL 0
444/** alloc physical memory */
445#define HPI_BUFFER_CMD_INTERNAL_ALLOC 1
446/** send physical memory address to adapter */
447#define HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER 2
448/** notify adapter to stop using physical buffer */
449#define HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER 3
450/** free physical buffer */
451#define HPI_BUFFER_CMD_INTERNAL_FREE 4
452
453/******************************************* CONTROLX ATTRIBUTES ****/
454/* NOTE: All controlx attributes must be unique, unlike control attributes */
455
456/*****************************************************************************/
457/*****************************************************************************/
458/******** HPI LOW LEVEL MESSAGES *******/
459/*****************************************************************************/
460/*****************************************************************************/
461/** Pnp ids */
462/** "ASI" - actual is "ASX" - need to change */
463#define HPI_ID_ISAPNP_AUDIOSCIENCE 0x0669
464/** PCI vendor ID that AudioScience uses */
465#define HPI_PCI_VENDOR_ID_AUDIOSCIENCE 0x175C
466/** PCI vendor ID that the DSP56301 has */
467#define HPI_PCI_VENDOR_ID_MOTOROLA 0x1057
468/** PCI vendor ID that TI uses */
469#define HPI_PCI_VENDOR_ID_TI 0x104C
470
471#define HPI_PCI_DEV_ID_PCI2040 0xAC60
472/** TI's C6205 PCI interface has this ID */
473#define HPI_PCI_DEV_ID_DSP6205 0xA106
474
475#define HPI_USB_VENDOR_ID_AUDIOSCIENCE 0x1257
476#define HPI_USB_W2K_TAG 0x57495341 /* "ASIW" */
477#define HPI_USB_LINUX_TAG 0x4C495341 /* "ASIL" */
478
479/** First 2 hex digits define the adapter family */
480#define HPI_ADAPTER_FAMILY_MASK 0xff00
481
482#define HPI_ADAPTER_FAMILY_ASI(f) (f & HPI_ADAPTER_FAMILY_MASK)
483#define HPI_ADAPTER_ASI(f) (f)
484
485/******************************************* message types */
486#define HPI_TYPE_MESSAGE 1
487#define HPI_TYPE_RESPONSE 2
488#define HPI_TYPE_DATA 3
489#define HPI_TYPE_SSX2BYPASS_MESSAGE 4
490
491/******************************************* object types */
492#define HPI_OBJ_SUBSYSTEM 1
493#define HPI_OBJ_ADAPTER 2
494#define HPI_OBJ_OSTREAM 3
495#define HPI_OBJ_ISTREAM 4
496#define HPI_OBJ_MIXER 5
497#define HPI_OBJ_NODE 6
498#define HPI_OBJ_CONTROL 7
499#define HPI_OBJ_NVMEMORY 8
500#define HPI_OBJ_GPIO 9
501#define HPI_OBJ_WATCHDOG 10
502#define HPI_OBJ_CLOCK 11
503#define HPI_OBJ_PROFILE 12
504#define HPI_OBJ_CONTROLEX 13
505#define HPI_OBJ_ASYNCEVENT 14
506
507#define HPI_OBJ_MAXINDEX 14
508
509/******************************************* methods/functions */
510
511#define HPI_OBJ_FUNCTION_SPACING 0x100
512#define HPI_MAKE_INDEX(obj, index) (obj * HPI_OBJ_FUNCTION_SPACING + index)
513#define HPI_EXTRACT_INDEX(fn) (fn & 0xff)
514
515/* SUB-SYSTEM */
516#define HPI_SUBSYS_OPEN HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 1)
517#define HPI_SUBSYS_GET_VERSION HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 2)
518#define HPI_SUBSYS_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 3)
519#define HPI_SUBSYS_FIND_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 4)
520#define HPI_SUBSYS_CREATE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 5)
521#define HPI_SUBSYS_CLOSE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 6)
522#define HPI_SUBSYS_DELETE_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 7)
523#define HPI_SUBSYS_DRIVER_LOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 8)
524#define HPI_SUBSYS_DRIVER_UNLOAD HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 9)
525#define HPI_SUBSYS_READ_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 10)
526#define HPI_SUBSYS_WRITE_PORT_8 HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 11)
527#define HPI_SUBSYS_GET_NUM_ADAPTERS HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 12)
528#define HPI_SUBSYS_GET_ADAPTER HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 13)
529#define HPI_SUBSYS_SET_NETWORK_INTERFACE HPI_MAKE_INDEX(HPI_OBJ_SUBSYSTEM, 14)
530#define HPI_SUBSYS_FUNCTION_COUNT 14
531/* ADAPTER */
532#define HPI_ADAPTER_OPEN HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 1)
533#define HPI_ADAPTER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 2)
534#define HPI_ADAPTER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 3)
535#define HPI_ADAPTER_GET_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 4)
536#define HPI_ADAPTER_TEST_ASSERT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 5)
537#define HPI_ADAPTER_SET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 6)
538#define HPI_ADAPTER_GET_MODE HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 7)
539#define HPI_ADAPTER_ENABLE_CAPABILITY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 8)
540#define HPI_ADAPTER_SELFTEST HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 9)
541#define HPI_ADAPTER_FIND_OBJECT HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 10)
542#define HPI_ADAPTER_QUERY_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 11)
543#define HPI_ADAPTER_START_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 12)
544#define HPI_ADAPTER_PROGRAM_FLASH HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 13)
545#define HPI_ADAPTER_SET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 14)
546#define HPI_ADAPTER_GET_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 15)
547#define HPI_ADAPTER_ENUM_PROPERTY HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 16)
548#define HPI_ADAPTER_MODULE_INFO HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 17)
549#define HPI_ADAPTER_DEBUG_READ HPI_MAKE_INDEX(HPI_OBJ_ADAPTER, 18)
550#define HPI_ADAPTER_FUNCTION_COUNT 18
551/* OUTPUT STREAM */
552#define HPI_OSTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 1)
553#define HPI_OSTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 2)
554#define HPI_OSTREAM_WRITE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 3)
555#define HPI_OSTREAM_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 4)
556#define HPI_OSTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 5)
557#define HPI_OSTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 6)
558#define HPI_OSTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 7)
559#define HPI_OSTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 8)
560#define HPI_OSTREAM_DATA HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 9)
561#define HPI_OSTREAM_SET_VELOCITY HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 10)
562#define HPI_OSTREAM_SET_PUNCHINOUT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 11)
563#define HPI_OSTREAM_SINEGEN HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 12)
564#define HPI_OSTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 13)
565#define HPI_OSTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 14)
566#define HPI_OSTREAM_ANC_READ HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 15)
567#define HPI_OSTREAM_SET_TIMESCALE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 16)
568#define HPI_OSTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 17)
569#define HPI_OSTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 18)
570#define HPI_OSTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 19)
571#define HPI_OSTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 20)
572#define HPI_OSTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 21)
573#define HPI_OSTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 22)
574#define HPI_OSTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 23)
575#define HPI_OSTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_OSTREAM, 24)
576#define HPI_OSTREAM_FUNCTION_COUNT 24
577/* INPUT STREAM */
578#define HPI_ISTREAM_OPEN HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 1)
579#define HPI_ISTREAM_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 2)
580#define HPI_ISTREAM_SET_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 3)
581#define HPI_ISTREAM_READ HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 4)
582#define HPI_ISTREAM_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 5)
583#define HPI_ISTREAM_STOP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 6)
584#define HPI_ISTREAM_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 7)
585#define HPI_ISTREAM_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 8)
586#define HPI_ISTREAM_QUERY_FORMAT HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 9)
587#define HPI_ISTREAM_ANC_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 10)
588#define HPI_ISTREAM_ANC_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 11)
589#define HPI_ISTREAM_ANC_WRITE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 12)
590#define HPI_ISTREAM_HOSTBUFFER_ALLOC HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 13)
591#define HPI_ISTREAM_HOSTBUFFER_FREE HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 14)
592#define HPI_ISTREAM_GROUP_ADD HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 15)
593#define HPI_ISTREAM_GROUP_GETMAP HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 16)
594#define HPI_ISTREAM_GROUP_RESET HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 17)
595#define HPI_ISTREAM_HOSTBUFFER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 18)
596#define HPI_ISTREAM_WAIT_START HPI_MAKE_INDEX(HPI_OBJ_ISTREAM, 19)
597#define HPI_ISTREAM_FUNCTION_COUNT 19
598/* MIXER */
599/* NOTE:
600 GET_NODE_INFO, SET_CONNECTION, GET_CONNECTIONS are not currently used */
601#define HPI_MIXER_OPEN HPI_MAKE_INDEX(HPI_OBJ_MIXER, 1)
602#define HPI_MIXER_CLOSE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 2)
603#define HPI_MIXER_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 3)
604#define HPI_MIXER_GET_NODE_INFO HPI_MAKE_INDEX(HPI_OBJ_MIXER, 4)
605#define HPI_MIXER_GET_CONTROL HPI_MAKE_INDEX(HPI_OBJ_MIXER, 5)
606#define HPI_MIXER_SET_CONNECTION HPI_MAKE_INDEX(HPI_OBJ_MIXER, 6)
607#define HPI_MIXER_GET_CONNECTIONS HPI_MAKE_INDEX(HPI_OBJ_MIXER, 7)
608#define HPI_MIXER_GET_CONTROL_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 8)
609#define HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX HPI_MAKE_INDEX(HPI_OBJ_MIXER, 9)
610#define HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES HPI_MAKE_INDEX(HPI_OBJ_MIXER, 10)
611#define HPI_MIXER_STORE HPI_MAKE_INDEX(HPI_OBJ_MIXER, 11)
612#define HPI_MIXER_FUNCTION_COUNT 11
613/* MIXER CONTROLS */
614#define HPI_CONTROL_GET_INFO HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 1)
615#define HPI_CONTROL_GET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 2)
616#define HPI_CONTROL_SET_STATE HPI_MAKE_INDEX(HPI_OBJ_CONTROL, 3)
617#define HPI_CONTROL_FUNCTION_COUNT 3
618/* NONVOL MEMORY */
619#define HPI_NVMEMORY_OPEN HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 1)
620#define HPI_NVMEMORY_READ_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 2)
621#define HPI_NVMEMORY_WRITE_BYTE HPI_MAKE_INDEX(HPI_OBJ_NVMEMORY, 3)
622#define HPI_NVMEMORY_FUNCTION_COUNT 3
623/* GPIO */
624#define HPI_GPIO_OPEN HPI_MAKE_INDEX(HPI_OBJ_GPIO, 1)
625#define HPI_GPIO_READ_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 2)
626#define HPI_GPIO_WRITE_BIT HPI_MAKE_INDEX(HPI_OBJ_GPIO, 3)
627#define HPI_GPIO_READ_ALL HPI_MAKE_INDEX(HPI_OBJ_GPIO, 4)
628#define HPI_GPIO_WRITE_STATUS HPI_MAKE_INDEX(HPI_OBJ_GPIO, 5)
629#define HPI_GPIO_FUNCTION_COUNT 5
630/* ASYNC EVENT */
631#define HPI_ASYNCEVENT_OPEN HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 1)
632#define HPI_ASYNCEVENT_CLOSE HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 2)
633#define HPI_ASYNCEVENT_WAIT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 3)
634#define HPI_ASYNCEVENT_GETCOUNT HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 4)
635#define HPI_ASYNCEVENT_GET HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 5)
636#define HPI_ASYNCEVENT_SENDEVENTS HPI_MAKE_INDEX(HPI_OBJ_ASYNCEVENT, 6)
637#define HPI_ASYNCEVENT_FUNCTION_COUNT 6
638/* WATCH-DOG */
639#define HPI_WATCHDOG_OPEN HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 1)
640#define HPI_WATCHDOG_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 2)
641#define HPI_WATCHDOG_PING HPI_MAKE_INDEX(HPI_OBJ_WATCHDOG, 3)
642/* CLOCK */
643#define HPI_CLOCK_OPEN HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 1)
644#define HPI_CLOCK_SET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 2)
645#define HPI_CLOCK_GET_TIME HPI_MAKE_INDEX(HPI_OBJ_CLOCK, 3)
646/* PROFILE */
647#define HPI_PROFILE_OPEN_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 1)
648#define HPI_PROFILE_START_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 2)
649#define HPI_PROFILE_STOP_ALL HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 3)
650#define HPI_PROFILE_GET HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 4)
651#define HPI_PROFILE_GET_IDLECOUNT HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 5)
652#define HPI_PROFILE_GET_NAME HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 6)
653#define HPI_PROFILE_GET_UTILIZATION HPI_MAKE_INDEX(HPI_OBJ_PROFILE, 7)
654#define HPI_PROFILE_FUNCTION_COUNT 7
655/* ////////////////////////////////////////////////////////////////////// */
656/* PRIVATE ATTRIBUTES */
657
658/* ////////////////////////////////////////////////////////////////////// */
659/* STRUCTURES */
660#ifndef DISABLE_PRAGMA_PACK1
661#pragma pack(push, 1)
662#endif
663
664/** PCI bus resource */
665struct hpi_pci {
666 u32 __iomem *ap_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
667 struct pci_dev *p_os_data;
668
669#ifndef HPI64BIT /* keep structure size constant */
670 u32 padding[HPI_MAX_ADAPTER_MEM_SPACES + 1];
671#endif
672 u16 vendor_id;
673 u16 device_id;
674 u16 subsys_vendor_id;
675 u16 subsys_device_id;
676 u16 bus_number;
677 u16 device_number;
678 u32 interrupt;
679};
680
681struct hpi_resource {
682 union {
683 const struct hpi_pci *pci;
684 const char *net_if;
685 } r;
686#ifndef HPI64BIT /* keep structure size constant */
687 u32 pad_to64;
688#endif
689 u16 bus_type; /* HPI_BUS_PNPISA, _PCI, _USB etc */
690 u16 padding;
691
692};
693
694/** Format info used inside struct hpi_message
695 Not the same as public API struct hpi_format */
696struct hpi_msg_format {
697 u32 sample_rate;
698 /**< 11025, 32000, 44100 ... */
699 u32 bit_rate; /**< for MPEG */
700 u32 attributes;
701 /**< Stereo/JointStereo/Mono */
702 u16 channels; /**< 1,2..., (or ancillary mode or idle bit */
703 u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see \ref HPI_FORMATS. */
704};
705
706/** Buffer+format structure.
707 Must be kept 7 * 32 bits to match public struct hpi_datastruct */
708struct hpi_msg_data {
709 struct hpi_msg_format format;
710 u8 *pb_data;
711#ifndef HPI64BIT
712 u32 padding;
713#endif
714 u32 data_size;
715};
716
717/** struct hpi_datastructure used up to 3.04 driver */
718struct hpi_data_legacy32 {
719 struct hpi_format format;
720 u32 pb_data;
721 u32 data_size;
722};
723
724#ifdef HPI64BIT
725/* Compatibility version of struct hpi_data*/
726struct hpi_data_compat32 {
727 struct hpi_msg_format format;
728 u32 pb_data;
729 u32 padding;
730 u32 data_size;
731};
732#endif
733
734struct hpi_buffer {
735 /** placehoder for backward compatability (see dwBufferSize) */
736 struct hpi_msg_format reserved;
737 u32 command; /**< HPI_BUFFER_CMD_xxx*/
738 u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
739 u32 buffer_size; /**< must line up with data_size of HPI_DATA*/
740};
741
742/*/////////////////////////////////////////////////////////////////////////// */
743/* This is used for background buffer bus mastering stream buffers. */
744struct hpi_hostbuffer_status {
745 u32 samples_processed;
746 u32 auxiliary_data_available;
747 u32 stream_state;
748 /* DSP index in to the host bus master buffer. */
749 u32 dSP_index;
750 /* Host index in to the host bus master buffer. */
751 u32 host_index;
752 u32 size_in_bytes;
753};
754
755struct hpi_streamid {
756 u16 object_type;
757 /**< Type of object, HPI_OBJ_OSTREAM or HPI_OBJ_ISTREAM. */
758 u16 stream_index; /**< outstream or instream index. */
759};
760
761struct hpi_punchinout {
762 u32 punch_in_sample;
763 u32 punch_out_sample;
764};
765
766struct hpi_subsys_msg {
767 struct hpi_resource resource;
768};
769
770struct hpi_subsys_res {
771 u32 version;
772 u32 data; /* used to return extended version */
773 u16 num_adapters; /* number of adapters */
774 u16 adapter_index;
775 u16 aw_adapter_list[HPI_MAX_ADAPTERS];
776};
777
778struct hpi_adapter_msg {
779 u32 adapter_mode; /* adapter mode */
780 u16 assert_id; /* assert number for "test assert" call
781 object_index for find object call
782 query_or_set for hpi_adapter_set_mode_ex() */
783 u16 object_type; /* for adapter find object call */
784};
785
786union hpi_adapterx_msg {
787 struct hpi_adapter_msg adapter;
788 struct {
789 u32 offset;
790 } query_flash;
791 struct {
792 u32 offset;
793 u32 length;
794 u32 key;
795 } start_flash;
796 struct {
797 u32 checksum;
798 u16 sequence;
799 u16 length;
800 u16 offset; /**< offset from start of msg to data */
801 u16 unused;
802 } program_flash;
803 struct {
804 u16 property;
805 u16 parameter1;
806 u16 parameter2;
807 } property_set;
808 struct {
809 u16 index;
810 u16 what;
811 u16 property_index;
812 } property_enum;
813 struct {
814 u16 index;
815 } module_info;
816 struct {
817 u32 dsp_address;
818 u32 count_bytes;
819 } debug_read;
820};
821
822struct hpi_adapter_res {
823 u32 serial_number;
824 u16 adapter_type;
825 u16 adapter_index; /* is this needed? also used for dsp_index */
826 u16 num_instreams;
827 u16 num_outstreams;
828 u16 num_mixers;
829 u16 version;
830 u8 sz_adapter_assert[HPI_STRING_LEN];
831};
832
833union hpi_adapterx_res {
834 struct hpi_adapter_res adapter;
835 struct {
836 u32 checksum;
837 u32 length;
838 u32 version;
839 } query_flash;
840 struct {
841 u16 sequence;
842 } program_flash;
843 struct {
844 u16 parameter1;
845 u16 parameter2;
846 } property_get;
847};
848
849struct hpi_stream_msg {
850 union {
851 struct hpi_msg_data data;
852 struct hpi_data_legacy32 data32;
853 u16 velocity;
854 struct hpi_punchinout pio;
855 u32 time_scale;
856 struct hpi_buffer buffer;
857 struct hpi_streamid stream;
858 } u;
859};
860
861struct hpi_stream_res {
862 union {
863 struct {
864 /* size of hardware buffer */
865 u32 buffer_size;
866 /* OutStream - data to play,
867 InStream - data recorded */
868 u32 data_available;
869 /* OutStream - samples played,
870 InStream - samples recorded */
871 u32 samples_transferred;
872 /* Adapter - OutStream - data to play,
873 InStream - data recorded */
874 u32 auxiliary_data_available;
875 u16 state; /* HPI_STATE_PLAYING, _STATE_STOPPED */
876 u16 padding;
877 } stream_info;
878 struct {
879 u32 buffer_size;
880 u32 data_available;
881 u32 samples_transfered;
882 u16 state;
883 u16 outstream_index;
884 u16 instream_index;
885 u16 padding;
886 u32 auxiliary_data_available;
887 } legacy_stream_info;
888 struct {
889 /* bitmap of grouped OutStreams */
890 u32 outstream_group_map;
891 /* bitmap of grouped InStreams */
892 u32 instream_group_map;
893 } group_info;
894 struct {
895 /* pointer to the buffer */
896 u8 *p_buffer;
897 /* pointer to the hostbuffer status */
898 struct hpi_hostbuffer_status *p_status;
899 } hostbuffer_info;
900 } u;
901};
902
903struct hpi_mixer_msg {
904 u16 control_index;
905 u16 control_type; /* = HPI_CONTROL_METER _VOLUME etc */
906 u16 padding1; /* maintain alignment of subsequent fields */
907 u16 node_type1; /* = HPI_SOURCENODE_LINEIN etc */
908 u16 node_index1; /* = 0..N */
909 u16 node_type2;
910 u16 node_index2;
911 u16 padding2; /* round to 4 bytes */
912};
913
914struct hpi_mixer_res {
915 u16 src_node_type; /* = HPI_SOURCENODE_LINEIN etc */
916 u16 src_node_index; /* = 0..N */
917 u16 dst_node_type;
918 u16 dst_node_index;
919 /* Also controlType for MixerGetControlByIndex */
920 u16 control_index;
921 /* may indicate which DSP the control is located on */
922 u16 dsp_index;
923};
924
925union hpi_mixerx_msg {
926 struct {
927 u16 starting_index;
928 u16 flags;
929 u32 length_in_bytes; /* length in bytes of p_data */
930 u32 p_data; /* pointer to a data array */
931 } gcabi;
932 struct {
933 u16 command;
934 u16 index;
935 } store; /* for HPI_MIXER_STORE message */
936};
937
938union hpi_mixerx_res {
939 struct {
940 u32 bytes_returned; /* size of items returned */
941 u32 p_data; /* pointer to data array */
942 u16 more_to_do; /* indicates if there is more to do */
943 } gcabi;
944};
945
946struct hpi_control_msg {
947 u16 attribute; /* control attribute or property */
948 u16 saved_index;
949 u32 param1; /* generic parameter 1 */
950 u32 param2; /* generic parameter 2 */
951 short an_log_value[HPI_MAX_CHANNELS];
952};
953
954struct hpi_control_union_msg {
955 u16 attribute; /* control attribute or property */
956 u16 saved_index; /* only used in ctrl save/restore */
957 union {
958 struct {
959 u32 param1; /* generic parameter 1 */
960 u32 param2; /* generic parameter 2 */
961 short an_log_value[HPI_MAX_CHANNELS];
962 } old;
963 union {
964 u32 frequency;
965 u32 gain;
966 u32 band;
967 u32 deemphasis;
968 u32 program;
969 struct {
970 u32 mode;
971 u32 value;
972 } mode;
973 } tuner;
974 } u;
975};
976
977struct hpi_control_res {
978 /* Could make union. dwParam, anLogValue never used in same response */
979 u32 param1;
980 u32 param2;
981 short an_log_value[HPI_MAX_CHANNELS];
982};
983
984union hpi_control_union_res {
985 struct {
986 u32 param1;
987 u32 param2;
988 short an_log_value[HPI_MAX_CHANNELS];
989 } old;
990 union {
991 u32 band;
992 u32 frequency;
993 u32 gain;
994 u32 level;
995 u32 deemphasis;
996 struct {
997 u32 data[2];
998 u32 bLER;
999 } rds;
1000 } tuner;
1001 struct {
1002 char sz_data[8];
1003 u32 remaining_chars;
1004 } chars8;
1005 char c_data12[12];
1006};
1007
1008/* HPI_CONTROLX_STRUCTURES */
1009
1010/* Message */
1011
1012/** Used for all HMI variables where max length <= 8 bytes
1013*/
1014struct hpi_controlx_msg_cobranet_data {
1015 u32 hmi_address;
1016 u32 byte_count;
1017 u32 data[2];
1018};
1019
1020/** Used for string data, and for packet bridge
1021*/
1022struct hpi_controlx_msg_cobranet_bigdata {
1023 u32 hmi_address;
1024 u32 byte_count;
1025 u8 *pb_data;
1026#ifndef HPI64BIT
1027 u32 padding;
1028#endif
1029};
1030
1031/** Used for PADS control reading of string fields.
1032*/
1033struct hpi_controlx_msg_pad_data {
1034 u32 field;
1035 u32 byte_count;
1036 u8 *pb_data;
1037#ifndef HPI64BIT
1038 u32 padding;
1039#endif
1040};
1041
1042/** Used for generic data
1043*/
1044
1045struct hpi_controlx_msg_generic {
1046 u32 param1;
1047 u32 param2;
1048};
1049
1050struct hpi_controlx_msg {
1051 u16 attribute; /* control attribute or property */
1052 u16 saved_index;
1053 union {
1054 struct hpi_controlx_msg_cobranet_data cobranet_data;
1055 struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata;
1056 struct hpi_controlx_msg_generic generic;
1057 struct hpi_controlx_msg_pad_data pad_data;
1058 /*struct param_value universal_value; */
1059 /* nothing extra to send for status read */
1060 } u;
1061};
1062
1063/* Response */
1064/**
1065*/
1066struct hpi_controlx_res_cobranet_data {
1067 u32 byte_count;
1068 u32 data[2];
1069};
1070
1071struct hpi_controlx_res_cobranet_bigdata {
1072 u32 byte_count;
1073};
1074
1075struct hpi_controlx_res_cobranet_status {
1076 u32 status;
1077 u32 readable_size;
1078 u32 writeable_size;
1079};
1080
1081struct hpi_controlx_res_generic {
1082 u32 param1;
1083 u32 param2;
1084};
1085
1086struct hpi_controlx_res {
1087 union {
1088 struct hpi_controlx_res_cobranet_bigdata cobranet_bigdata;
1089 struct hpi_controlx_res_cobranet_data cobranet_data;
1090 struct hpi_controlx_res_cobranet_status cobranet_status;
1091 struct hpi_controlx_res_generic generic;
1092 /*struct param_info universal_info; */
1093 /*struct param_value universal_value; */
1094 } u;
1095};
1096
1097struct hpi_nvmemory_msg {
1098 u16 address;
1099 u16 data;
1100};
1101
1102struct hpi_nvmemory_res {
1103 u16 size_in_bytes;
1104 u16 data;
1105};
1106
1107struct hpi_gpio_msg {
1108 u16 bit_index;
1109 u16 bit_data;
1110};
1111
1112struct hpi_gpio_res {
1113 u16 number_input_bits;
1114 u16 number_output_bits;
1115 u16 bit_data[4];
1116};
1117
1118struct hpi_async_msg {
1119 u32 events;
1120 u16 maximum_events;
1121 u16 padding;
1122};
1123
1124struct hpi_async_res {
1125 union {
1126 struct {
1127 u16 count;
1128 } count;
1129 struct {
1130 u32 events;
1131 u16 number_returned;
1132 u16 padding;
1133 } get;
1134 struct hpi_async_event event;
1135 } u;
1136};
1137
1138struct hpi_watchdog_msg {
1139 u32 time_ms;
1140};
1141
1142struct hpi_watchdog_res {
1143 u32 time_ms;
1144};
1145
1146struct hpi_clock_msg {
1147 u16 hours;
1148 u16 minutes;
1149 u16 seconds;
1150 u16 milli_seconds;
1151};
1152
1153struct hpi_clock_res {
1154 u16 size_in_bytes;
1155 u16 hours;
1156 u16 minutes;
1157 u16 seconds;
1158 u16 milli_seconds;
1159 u16 padding;
1160};
1161
1162struct hpi_profile_msg {
1163 u16 bin_index;
1164 u16 padding;
1165};
1166
1167struct hpi_profile_res_open {
1168 u16 max_profiles;
1169};
1170
1171struct hpi_profile_res_time {
1172 u32 micro_seconds;
1173 u32 call_count;
1174 u32 max_micro_seconds;
1175 u32 min_micro_seconds;
1176 u16 seconds;
1177};
1178
1179struct hpi_profile_res_name {
1180 u8 sz_name[32];
1181};
1182
1183struct hpi_profile_res {
1184 union {
1185 struct hpi_profile_res_open o;
1186 struct hpi_profile_res_time t;
1187 struct hpi_profile_res_name n;
1188 } u;
1189};
1190
1191struct hpi_message_header {
1192 u16 size; /* total size in bytes */
1193 u8 type; /* HPI_TYPE_MESSAGE */
1194 u8 version; /* message version */
1195 u16 object; /* HPI_OBJ_* */
1196 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1197 u16 adapter_index; /* the adapter index */
1198 u16 obj_index; /* */
1199};
1200
1201struct hpi_message {
1202 /* following fields must match HPI_MESSAGE_HEADER */
1203 u16 size; /* total size in bytes */
1204 u8 type; /* HPI_TYPE_MESSAGE */
1205 u8 version; /* message version */
1206 u16 object; /* HPI_OBJ_* */
1207 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1208 u16 adapter_index; /* the adapter index */
1209 u16 obj_index; /* */
1210 union {
1211 struct hpi_subsys_msg s;
1212 struct hpi_adapter_msg a;
1213 union hpi_adapterx_msg ax;
1214 struct hpi_stream_msg d;
1215 struct hpi_mixer_msg m;
1216 union hpi_mixerx_msg mx; /* extended mixer; */
1217 struct hpi_control_msg c; /* mixer control; */
1218 /* identical to struct hpi_control_msg,
1219 but field naming is improved */
1220 struct hpi_control_union_msg cu;
1221 struct hpi_controlx_msg cx; /* extended mixer control; */
1222 struct hpi_nvmemory_msg n;
1223 struct hpi_gpio_msg l; /* digital i/o */
1224 struct hpi_watchdog_msg w;
1225 struct hpi_clock_msg t; /* dsp time */
1226 struct hpi_profile_msg p;
1227 struct hpi_async_msg as;
1228 char fixed_size[32];
1229 } u;
1230};
1231
1232#define HPI_MESSAGE_SIZE_BY_OBJECT { \
1233 sizeof(struct hpi_message_header) , /* default, no object type 0 */ \
1234 sizeof(struct hpi_message_header) + sizeof(struct hpi_subsys_msg),\
1235 sizeof(struct hpi_message_header) + sizeof(union hpi_adapterx_msg),\
1236 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
1237 sizeof(struct hpi_message_header) + sizeof(struct hpi_stream_msg),\
1238 sizeof(struct hpi_message_header) + sizeof(struct hpi_mixer_msg),\
1239 sizeof(struct hpi_message_header) , /* no node message */ \
1240 sizeof(struct hpi_message_header) + sizeof(struct hpi_control_msg),\
1241 sizeof(struct hpi_message_header) + sizeof(struct hpi_nvmemory_msg),\
1242 sizeof(struct hpi_message_header) + sizeof(struct hpi_gpio_msg),\
1243 sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
1244 sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
1245 sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
1246 sizeof(struct hpi_message_header) + sizeof(struct hpi_controlx_msg),\
1247 sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
1248}
1249
1250struct hpi_response_header {
1251 u16 size;
1252 u8 type; /* HPI_TYPE_RESPONSE */
1253 u8 version; /* response version */
1254 u16 object; /* HPI_OBJ_* */
1255 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1256 u16 error; /* HPI_ERROR_xxx */
1257 u16 specific_error; /* adapter specific error */
1258};
1259
1260struct hpi_response {
1261/* following fields must match HPI_RESPONSE_HEADER */
1262 u16 size;
1263 u8 type; /* HPI_TYPE_RESPONSE */
1264 u8 version; /* response version */
1265 u16 object; /* HPI_OBJ_* */
1266 u16 function; /* HPI_SUBSYS_xxx, HPI_ADAPTER_xxx */
1267 u16 error; /* HPI_ERROR_xxx */
1268 u16 specific_error; /* adapter specific error */
1269 union {
1270 struct hpi_subsys_res s;
1271 struct hpi_adapter_res a;
1272 union hpi_adapterx_res ax;
1273 struct hpi_stream_res d;
1274 struct hpi_mixer_res m;
1275 union hpi_mixerx_res mx; /* extended mixer; */
1276 struct hpi_control_res c; /* mixer control; */
1277 /* identical to hpi_control_res, but field naming is improved */
1278 union hpi_control_union_res cu;
1279 struct hpi_controlx_res cx; /* extended mixer control; */
1280 struct hpi_nvmemory_res n;
1281 struct hpi_gpio_res l; /* digital i/o */
1282 struct hpi_watchdog_res w;
1283 struct hpi_clock_res t; /* dsp time */
1284 struct hpi_profile_res p;
1285 struct hpi_async_res as;
1286 u8 bytes[52];
1287 } u;
1288};
1289
1290#define HPI_RESPONSE_SIZE_BY_OBJECT { \
1291 sizeof(struct hpi_response_header) ,/* default, no object type 0 */ \
1292 sizeof(struct hpi_response_header) + sizeof(struct hpi_subsys_res),\
1293 sizeof(struct hpi_response_header) + sizeof(union hpi_adapterx_res),\
1294 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
1295 sizeof(struct hpi_response_header) + sizeof(struct hpi_stream_res),\
1296 sizeof(struct hpi_response_header) + sizeof(struct hpi_mixer_res),\
1297 sizeof(struct hpi_response_header) , /* no node response */ \
1298 sizeof(struct hpi_response_header) + sizeof(struct hpi_control_res),\
1299 sizeof(struct hpi_response_header) + sizeof(struct hpi_nvmemory_res),\
1300 sizeof(struct hpi_response_header) + sizeof(struct hpi_gpio_res),\
1301 sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
1302 sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
1303 sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
1304 sizeof(struct hpi_response_header) + sizeof(struct hpi_controlx_res),\
1305 sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
1306}
1307
1308/*********************** version 1 message/response *****************************/
1309#define HPINET_ETHERNET_DATA_SIZE (1500)
1310#define HPINET_IP_HDR_SIZE (20)
1311#define HPINET_IP_DATA_SIZE (HPINET_ETHERNET_DATA_SIZE - HPINET_IP_HDR_SIZE)
1312#define HPINET_UDP_HDR_SIZE (8)
1313#define HPINET_UDP_DATA_SIZE (HPINET_IP_DATA_SIZE - HPINET_UDP_HDR_SIZE)
1314#define HPINET_ASI_HDR_SIZE (2)
1315#define HPINET_ASI_DATA_SIZE (HPINET_UDP_DATA_SIZE - HPINET_ASI_HDR_SIZE)
1316
1317#define HPI_MAX_PAYLOAD_SIZE (HPINET_ASI_DATA_SIZE - 2)
1318
1319/* New style message/response, but still V0 compatible */
1320struct hpi_msg_adapter_get_info {
1321 struct hpi_message_header h;
1322};
1323
1324struct hpi_res_adapter_get_info {
1325 struct hpi_response_header h; /*v0 */
1326 struct hpi_adapter_res p;
1327};
1328
1329/* padding is so these are same size as v0 hpi_message */
1330struct hpi_msg_adapter_query_flash {
1331 struct hpi_message_header h;
1332 u32 offset;
1333 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
1334 sizeof(struct hpi_message_header) - 1 * sizeof(u32)];
1335};
1336
1337/* padding is so these are same size as v0 hpi_response */
1338struct hpi_res_adapter_query_flash {
1339 struct hpi_response_header h;
1340 u32 checksum;
1341 u32 length;
1342 u32 version;
1343 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1344 sizeof(struct hpi_response_header) - 3 * sizeof(u32)];
1345};
1346
1347struct hpi_msg_adapter_start_flash {
1348 struct hpi_message_header h;
1349 u32 offset;
1350 u32 length;
1351 u32 key;
1352 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */
1353 sizeof(struct hpi_message_header) - 3 * sizeof(u32)];
1354};
1355
1356struct hpi_res_adapter_start_flash {
1357 struct hpi_response_header h;
1358 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1359 sizeof(struct hpi_response_header)];
1360};
1361
1362struct hpi_msg_adapter_program_flash_payload {
1363 u32 checksum;
1364 u16 sequence;
1365 u16 length;
1366 u16 offset; /**< offset from start of msg to data */
1367 u16 unused;
1368 /* ensure sizeof(header + payload) == sizeof(hpi_message_V0)
1369 because old firmware expects data after message of this size */
1370 u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 message */
1371 sizeof(struct hpi_message_header) - sizeof(u32) -
1372 4 * sizeof(u16)];
1373};
1374
1375struct hpi_msg_adapter_program_flash {
1376 struct hpi_message_header h;
1377 struct hpi_msg_adapter_program_flash_payload p;
1378 u32 data[256];
1379};
1380
1381struct hpi_res_adapter_program_flash {
1382 struct hpi_response_header h;
1383 u16 sequence;
1384 u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */
1385 sizeof(struct hpi_response_header) - sizeof(u16)];
1386};
1387
1388#if 1
1389#define hpi_message_header_v1 hpi_message_header
1390#define hpi_response_header_v1 hpi_response_header
1391#else
1392/* V1 headers in Addition to v0 headers */
1393struct hpi_message_header_v1 {
1394 struct hpi_message_header h0;
1395/* struct {
1396} h1; */
1397};
1398
1399struct hpi_response_header_v1 {
1400 struct hpi_response_header h0;
1401 struct {
1402 u16 adapter_index; /* the adapter index */
1403 u16 obj_index; /* object index */
1404 } h1;
1405};
1406#endif
1407
1408/* STRV HPI Packet */
1409struct hpi_msg_strv {
1410 struct hpi_message_header h;
1411 struct hpi_entity strv;
1412};
1413
1414struct hpi_res_strv {
1415 struct hpi_response_header h;
1416 struct hpi_entity strv;
1417};
1418#define MIN_STRV_PACKET_SIZE sizeof(struct hpi_res_strv)
1419
1420struct hpi_msg_payload_v0 {
1421 struct hpi_message_header h;
1422 union {
1423 struct hpi_subsys_msg s;
1424 struct hpi_adapter_msg a;
1425 union hpi_adapterx_msg ax;
1426 struct hpi_stream_msg d;
1427 struct hpi_mixer_msg m;
1428 union hpi_mixerx_msg mx;
1429 struct hpi_control_msg c;
1430 struct hpi_control_union_msg cu;
1431 struct hpi_controlx_msg cx;
1432 struct hpi_nvmemory_msg n;
1433 struct hpi_gpio_msg l;
1434 struct hpi_watchdog_msg w;
1435 struct hpi_clock_msg t;
1436 struct hpi_profile_msg p;
1437 struct hpi_async_msg as;
1438 } u;
1439};
1440
1441struct hpi_res_payload_v0 {
1442 struct hpi_response_header h;
1443 union {
1444 struct hpi_subsys_res s;
1445 struct hpi_adapter_res a;
1446 union hpi_adapterx_res ax;
1447 struct hpi_stream_res d;
1448 struct hpi_mixer_res m;
1449 union hpi_mixerx_res mx;
1450 struct hpi_control_res c;
1451 union hpi_control_union_res cu;
1452 struct hpi_controlx_res cx;
1453 struct hpi_nvmemory_res n;
1454 struct hpi_gpio_res l;
1455 struct hpi_watchdog_res w;
1456 struct hpi_clock_res t;
1457 struct hpi_profile_res p;
1458 struct hpi_async_res as;
1459 } u;
1460};
1461
1462union hpi_message_buffer_v1 {
1463 struct hpi_message m0; /* version 0 */
1464 struct hpi_message_header_v1 h;
1465 unsigned char buf[HPI_MAX_PAYLOAD_SIZE];
1466};
1467
1468union hpi_response_buffer_v1 {
1469 struct hpi_response r0; /* version 0 */
1470 struct hpi_response_header_v1 h;
1471 unsigned char buf[HPI_MAX_PAYLOAD_SIZE];
1472};
1473
1474compile_time_assert((sizeof(union hpi_message_buffer_v1) <=
1475 HPI_MAX_PAYLOAD_SIZE), message_buffer_ok);
1476compile_time_assert((sizeof(union hpi_response_buffer_v1) <=
1477 HPI_MAX_PAYLOAD_SIZE), response_buffer_ok);
1478
1479/*////////////////////////////////////////////////////////////////////////// */
1480/* declarations for compact control calls */
1481struct hpi_control_defn {
1482 u8 type;
1483 u8 channels;
1484 u8 src_node_type;
1485 u8 src_node_index;
1486 u8 dest_node_type;
1487 u8 dest_node_index;
1488};
1489
1490/*////////////////////////////////////////////////////////////////////////// */
1491/* declarations for control caching (internal to HPI<->DSP interaction) */
1492
1493/** A compact representation of (part of) a controls state.
1494Used for efficient transfer of the control state
1495between DSP and host or across a network
1496*/
1497struct hpi_control_cache_info {
1498 /** one of HPI_CONTROL_* */
1499 u8 control_type;
1500 /** The total size of cached information in 32-bit words. */
1501 u8 size_in32bit_words;
1502 /** The original index of the control on the DSP */
1503 u16 control_index;
1504};
1505
1506struct hpi_control_cache_single {
1507 struct hpi_control_cache_info i;
1508 union {
1509 struct { /* volume */
1510 u16 an_log[2];
1511 } v;
1512 struct { /* peak meter */
1513 u16 an_log_peak[2];
1514 u16 an_logRMS[2];
1515 } p;
1516 struct { /* channel mode */
1517 u16 mode;
1518 } m;
1519 struct { /* multiplexer */
1520 u16 source_node_type;
1521 u16 source_node_index;
1522 } x;
1523 struct { /* level/trim */
1524 u16 an_log[2];
1525 } l;
1526 struct { /* tuner - partial caching.
1527 some attributes go to the DSP. */
1528 u32 freq_ink_hz;
1529 u16 band;
1530 u16 level;
1531 } t;
1532 struct { /* AESEBU rx status */
1533 u32 error_status;
1534 u32 source;
1535 } aes3rx;
1536 struct { /* AESEBU tx */
1537 u32 format;
1538 } aes3tx;
1539 struct { /* tone detector */
1540 u16 state;
1541 } tone;
1542 struct { /* silence detector */
1543 u32 state;
1544 u32 count;
1545 } silence;
1546 struct { /* sample clock */
1547 u16 source;
1548 u16 source_index;
1549 u32 sample_rate;
1550 } clk;
1551 struct { /* microphone control */
1552 u16 state;
1553 } phantom_power;
1554 struct { /* generic control */
1555 u32 dw1;
1556 u32 dw2;
1557 } g;
1558 } u;
1559};
1560
1561struct hpi_control_cache_pad {
1562 struct hpi_control_cache_info i;
1563 u32 field_valid_flags;
1564 u8 c_channel[8];
1565 u8 c_artist[40];
1566 u8 c_title[40];
1567 u8 c_comment[200];
1568 u32 pTY;
1569 u32 pI;
1570 u32 traffic_supported;
1571 u32 traffic_anouncement;
1572};
1573
1574/*/////////////////////////////////////////////////////////////////////////// */
1575/* declarations for 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */
1576struct hpi_fifo_buffer {
1577 u32 size;
1578 u32 dSP_index;
1579 u32 host_index;
1580};
1581
1582#ifndef DISABLE_PRAGMA_PACK1
1583#pragma pack(pop)
1584#endif
1585
1586/* skip host side function declarations for DSP
1587 compile and documentation extraction */
1588
1589char hpi_handle_object(const u32 handle);
1590
1591void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
1592 u16 *pw_object_index);
1593
1594u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
1595 const u16 object_index);
1596
1597/*////////////////////////////////////////////////////////////////////////// */
1598
1599/* main HPI entry point */
1600hpi_handler_func hpi_send_recv;
1601
1602/* UDP message */
1603void hpi_send_recvUDP(struct hpi_message *phm, struct hpi_response *phr,
1604 const unsigned int timeout);
1605
1606/* used in PnP OS/driver */
1607u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
1608 const struct hpi_resource *p_resource, u16 *pw_adapter_index);
1609
1610u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys,
1611 u16 adapter_index);
1612
1613u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1614 u32 h_outstream, u8 **pp_buffer,
1615 struct hpi_hostbuffer_status **pp_status);
1616
1617u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1618 u32 h_instream, u8 **pp_buffer,
1619 struct hpi_hostbuffer_status **pp_status);
1620
1621u16 hpi_adapter_restart(u16 adapter_index);
1622
1623/*
1624The following 3 functions were last declared in header files for
1625driver 3.10. HPI_ControlQuery() used to be the recommended way
1626of getting a volume range. Declared here for binary asihpi32.dll
1627compatibility.
1628*/
1629
1630void hpi_format_to_msg(struct hpi_msg_format *pMF,
1631 const struct hpi_format *pF);
1632void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
1633
1634/*////////////////////////////////////////////////////////////////////////// */
1635/* declarations for individual HPI entry points */
1636hpi_handler_func HPI_1000;
1637hpi_handler_func HPI_6000;
1638hpi_handler_func HPI_6205;
1639hpi_handler_func HPI_COMMON;
1640
1641#endif /* _HPI_INTERNAL_H_ */
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c
new file mode 100644
index 000000000000..565102cae4f8
--- /dev/null
+++ b/sound/pci/asihpi/hpicmn.c
@@ -0,0 +1,643 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19\file hpicmn.c
20
21 Common functions used by hpixxxx.c modules
22
23(C) Copyright AudioScience Inc. 1998-2003
24*******************************************************************************/
25#define SOURCEFILE_NAME "hpicmn.c"
26
27#include "hpi_internal.h"
28#include "hpidebug.h"
29#include "hpicmn.h"
30
31struct hpi_adapters_list {
32 struct hpios_spinlock list_lock;
33 struct hpi_adapter_obj adapter[HPI_MAX_ADAPTERS];
34 u16 gw_num_adapters;
35};
36
37static struct hpi_adapters_list adapters;
38
39/**
40* Given an HPI Message that was sent out and a response that was received,
41* validate that the response has the correct fields filled in,
42* i.e ObjectType, Function etc
43**/
44u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
45{
46 u16 error = 0;
47
48 if ((phr->type != HPI_TYPE_RESPONSE)
49 || (phr->object != phm->object)
50 || (phr->function != phm->function))
51 error = HPI_ERROR_INVALID_RESPONSE;
52
53 return error;
54}
55
56u16 hpi_add_adapter(struct hpi_adapter_obj *pao)
57{
58 u16 retval = 0;
59 /*HPI_ASSERT(pao->wAdapterType); */
60
61 hpios_alistlock_lock(&adapters);
62
63 if (pao->index >= HPI_MAX_ADAPTERS) {
64 retval = HPI_ERROR_BAD_ADAPTER_NUMBER;
65 goto unlock;
66 }
67
68 if (adapters.adapter[pao->index].adapter_type) {
69 {
70 retval = HPI_DUPLICATE_ADAPTER_NUMBER;
71 goto unlock;
72 }
73 }
74 adapters.adapter[pao->index] = *pao;
75 hpios_dsplock_init(&adapters.adapter[pao->index]);
76 adapters.gw_num_adapters++;
77
78unlock:
79 hpios_alistlock_un_lock(&adapters);
80 return retval;
81}
82
83void hpi_delete_adapter(struct hpi_adapter_obj *pao)
84{
85 memset(pao, 0, sizeof(struct hpi_adapter_obj));
86
87 hpios_alistlock_lock(&adapters);
88 adapters.gw_num_adapters--; /* dec the number of adapters */
89 hpios_alistlock_un_lock(&adapters);
90}
91
92/**
93* FindAdapter returns a pointer to the struct hpi_adapter_obj with
94* index wAdapterIndex in an HPI_ADAPTERS_LIST structure.
95*
96*/
97struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index)
98{
99 struct hpi_adapter_obj *pao = NULL;
100
101 if (adapter_index >= HPI_MAX_ADAPTERS) {
102 HPI_DEBUG_LOG(VERBOSE, "find_adapter invalid index %d ",
103 adapter_index);
104 return NULL;
105 }
106
107 pao = &adapters.adapter[adapter_index];
108 if (pao->adapter_type != 0) {
109 /*
110 HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
111 wAdapterIndex);
112 */
113 return pao;
114 } else {
115 /*
116 HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
117 wAdapterIndex);
118 */
119 return NULL;
120 }
121}
122
123/**
124*
125* wipe an HPI_ADAPTERS_LIST structure.
126*
127**/
128static void wipe_adapter_list(void
129 )
130{
131 memset(&adapters, 0, sizeof(adapters));
132}
133
134/**
135* SubSysGetAdapters fills awAdapterList in an struct hpi_response structure
136* with all adapters in the given HPI_ADAPTERS_LIST.
137*
138*/
139static void subsys_get_adapters(struct hpi_response *phr)
140{
141 /* fill in the response adapter array with the position */
142 /* identified by the adapter number/index of the adapters in */
143 /* this HPI */
144 /* i.e. if we have an A120 with it's jumper set to */
145 /* Adapter Number 2 then put an Adapter type A120 in the */
146 /* array in position 1 */
147 /* NOTE: AdapterNumber is 1..N, Index is 0..N-1 */
148
149 /* input: NONE */
150 /* output: wNumAdapters */
151 /* awAdapter[] */
152 /* */
153
154 short i;
155 struct hpi_adapter_obj *pao = NULL;
156
157 HPI_DEBUG_LOG(VERBOSE, "subsys_get_adapters\n");
158
159 /* for each adapter, place it's type in the position of the array */
160 /* corresponding to it's adapter number */
161 for (i = 0; i < adapters.gw_num_adapters; i++) {
162 pao = &adapters.adapter[i];
163 if (phr->u.s.aw_adapter_list[pao->index] != 0) {
164 phr->error = HPI_DUPLICATE_ADAPTER_NUMBER;
165 phr->specific_error = pao->index;
166 return;
167 }
168 phr->u.s.aw_adapter_list[pao->index] = pao->adapter_type;
169 }
170
171 phr->u.s.num_adapters = adapters.gw_num_adapters;
172 phr->error = 0; /* the function completed OK; */
173}
174
175static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC)
176{
177 unsigned int i;
178 int cached = 0;
179 if (!pC)
180 return 0;
181 if ((!pC->init) && (pC->p_cache != NULL) && (pC->control_count)
182 && (pC->cache_size_in_bytes)
183 ) {
184 u32 *p_master_cache;
185 pC->init = 1;
186
187 p_master_cache = (u32 *)pC->p_cache;
188 HPI_DEBUG_LOG(VERBOSE, "check %d controls\n",
189 pC->control_count);
190 for (i = 0; i < pC->control_count; i++) {
191 struct hpi_control_cache_info *info =
192 (struct hpi_control_cache_info *)
193 p_master_cache;
194
195 if (info->control_type) {
196 pC->p_info[i] = info;
197 cached++;
198 } else
199 pC->p_info[i] = NULL;
200
201 if (info->size_in32bit_words)
202 p_master_cache += info->size_in32bit_words;
203 else
204 p_master_cache +=
205 sizeof(struct
206 hpi_control_cache_single) /
207 sizeof(u32);
208
209 HPI_DEBUG_LOG(VERBOSE,
210 "cached %d, pinfo %p index %d type %d\n",
211 cached, pC->p_info[i], info->control_index,
212 info->control_type);
213 }
214 /*
215 We didn't find anything to cache, so try again later !
216 */
217 if (!cached)
218 pC->init = 0;
219 }
220 return pC->init;
221}
222
223/** Find a control.
224*/
225static short find_control(struct hpi_message *phm,
226 struct hpi_control_cache *p_cache, struct hpi_control_cache_info **pI,
227 u16 *pw_control_index)
228{
229 *pw_control_index = phm->obj_index;
230
231 if (!control_cache_alloc_check(p_cache)) {
232 HPI_DEBUG_LOG(VERBOSE,
233 "control_cache_alloc_check() failed. adap%d ci%d\n",
234 phm->adapter_index, *pw_control_index);
235 return 0;
236 }
237
238 *pI = p_cache->p_info[*pw_control_index];
239 if (!*pI) {
240 HPI_DEBUG_LOG(VERBOSE, "uncached adap %d, control %d\n",
241 phm->adapter_index, *pw_control_index);
242 return 0;
243 } else {
244 HPI_DEBUG_LOG(VERBOSE, "find_control() type %d\n",
245 (*pI)->control_type);
246 }
247 return 1;
248}
249
250/** Used by the kernel driver to figure out if a buffer needs mapping.
251 */
252short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
253 struct hpi_message *phm, void **p, unsigned int *pN)
254{
255 *pN = 0;
256 *p = NULL;
257 if ((phm->function == HPI_CONTROL_GET_STATE)
258 && (phm->object == HPI_OBJ_CONTROLEX)
259 ) {
260 u16 control_index;
261 struct hpi_control_cache_info *pI;
262
263 if (!find_control(phm, p_cache, &pI, &control_index))
264 return 0;
265 }
266 return 0;
267}
268
269/* allow unified treatment of several string fields within struct */
270#define HPICMN_PAD_OFS_AND_SIZE(m) {\
271 offsetof(struct hpi_control_cache_pad, m), \
272 sizeof(((struct hpi_control_cache_pad *)(NULL))->m) }
273
274struct pad_ofs_size {
275 unsigned int offset;
276 unsigned int field_size;
277};
278
279static struct pad_ofs_size pad_desc[] = {
280 HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */
281 HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */
282 HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */
283 HPICMN_PAD_OFS_AND_SIZE(c_comment), /* HPI_PAD_COMMENT */
284};
285
286/** CheckControlCache checks the cache and fills the struct hpi_response
287 * accordingly. It returns one if a cache hit occurred, zero otherwise.
288 */
289short hpi_check_control_cache(struct hpi_control_cache *p_cache,
290 struct hpi_message *phm, struct hpi_response *phr)
291{
292 short found = 1;
293 u16 control_index;
294 struct hpi_control_cache_info *pI;
295 struct hpi_control_cache_single *pC;
296 struct hpi_control_cache_pad *p_pad;
297
298 if (!find_control(phm, p_cache, &pI, &control_index))
299 return 0;
300
301 phr->error = 0;
302
303 /* pC is the default cached control strucure. May be cast to
304 something else in the following switch statement.
305 */
306 pC = (struct hpi_control_cache_single *)pI;
307 p_pad = (struct hpi_control_cache_pad *)pI;
308
309 switch (pI->control_type) {
310
311 case HPI_CONTROL_METER:
312 if (phm->u.c.attribute == HPI_METER_PEAK) {
313 phr->u.c.an_log_value[0] = pC->u.p.an_log_peak[0];
314 phr->u.c.an_log_value[1] = pC->u.p.an_log_peak[1];
315 } else if (phm->u.c.attribute == HPI_METER_RMS) {
316 phr->u.c.an_log_value[0] = pC->u.p.an_logRMS[0];
317 phr->u.c.an_log_value[1] = pC->u.p.an_logRMS[1];
318 } else
319 found = 0;
320 break;
321 case HPI_CONTROL_VOLUME:
322 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
323 phr->u.c.an_log_value[0] = pC->u.v.an_log[0];
324 phr->u.c.an_log_value[1] = pC->u.v.an_log[1];
325 } else
326 found = 0;
327 break;
328 case HPI_CONTROL_MULTIPLEXER:
329 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
330 phr->u.c.param1 = pC->u.x.source_node_type;
331 phr->u.c.param2 = pC->u.x.source_node_index;
332 } else {
333 found = 0;
334 }
335 break;
336 case HPI_CONTROL_CHANNEL_MODE:
337 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
338 phr->u.c.param1 = pC->u.m.mode;
339 else
340 found = 0;
341 break;
342 case HPI_CONTROL_LEVEL:
343 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
344 phr->u.c.an_log_value[0] = pC->u.l.an_log[0];
345 phr->u.c.an_log_value[1] = pC->u.l.an_log[1];
346 } else
347 found = 0;
348 break;
349 case HPI_CONTROL_TUNER:
350 {
351 struct hpi_control_cache_single *pCT =
352 (struct hpi_control_cache_single *)pI;
353 if (phm->u.c.attribute == HPI_TUNER_FREQ)
354 phr->u.c.param1 = pCT->u.t.freq_ink_hz;
355 else if (phm->u.c.attribute == HPI_TUNER_BAND)
356 phr->u.c.param1 = pCT->u.t.band;
357 else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
358 && (phm->u.c.param1 ==
359 HPI_TUNER_LEVEL_AVERAGE))
360 phr->u.c.param1 = pCT->u.t.level;
361 else
362 found = 0;
363 }
364 break;
365 case HPI_CONTROL_AESEBU_RECEIVER:
366 if (phm->u.c.attribute == HPI_AESEBURX_ERRORSTATUS)
367 phr->u.c.param1 = pC->u.aes3rx.error_status;
368 else if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
369 phr->u.c.param1 = pC->u.aes3rx.source;
370 else
371 found = 0;
372 break;
373 case HPI_CONTROL_AESEBU_TRANSMITTER:
374 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
375 phr->u.c.param1 = pC->u.aes3tx.format;
376 else
377 found = 0;
378 break;
379 case HPI_CONTROL_TONEDETECTOR:
380 if (phm->u.c.attribute == HPI_TONEDETECTOR_STATE)
381 phr->u.c.param1 = pC->u.tone.state;
382 else
383 found = 0;
384 break;
385 case HPI_CONTROL_SILENCEDETECTOR:
386 if (phm->u.c.attribute == HPI_SILENCEDETECTOR_STATE) {
387 phr->u.c.param1 = pC->u.silence.state;
388 phr->u.c.param2 = pC->u.silence.count;
389 } else
390 found = 0;
391 break;
392 case HPI_CONTROL_MICROPHONE:
393 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
394 phr->u.c.param1 = pC->u.phantom_power.state;
395 else
396 found = 0;
397 break;
398 case HPI_CONTROL_SAMPLECLOCK:
399 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
400 phr->u.c.param1 = pC->u.clk.source;
401 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX) {
402 if (pC->u.clk.source_index ==
403 HPI_ERROR_ILLEGAL_CACHE_VALUE) {
404 phr->u.c.param1 = 0;
405 phr->error = HPI_ERROR_INVALID_OPERATION;
406 } else
407 phr->u.c.param1 = pC->u.clk.source_index;
408 } else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
409 phr->u.c.param1 = pC->u.clk.sample_rate;
410 else
411 found = 0;
412 break;
413 case HPI_CONTROL_PAD:
414
415 if (!(p_pad->field_valid_flags & (1 <<
416 HPI_CTL_ATTR_INDEX(phm->u.c.
417 attribute)))) {
418 phr->error = HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
419 break;
420 }
421
422 if (phm->u.c.attribute == HPI_PAD_PROGRAM_ID)
423 phr->u.c.param1 = p_pad->pI;
424 else if (phm->u.c.attribute == HPI_PAD_PROGRAM_TYPE)
425 phr->u.c.param1 = p_pad->pTY;
426 else {
427 unsigned int index =
428 HPI_CTL_ATTR_INDEX(phm->u.c.attribute) - 1;
429 unsigned int offset = phm->u.c.param1;
430 unsigned int pad_string_len, field_size;
431 char *pad_string;
432 unsigned int tocopy;
433
434 HPI_DEBUG_LOG(VERBOSE, "PADS HPI_PADS_ %d\n",
435 phm->u.c.attribute);
436
437 if (index > ARRAY_SIZE(pad_desc) - 1) {
438 phr->error =
439 HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
440 break;
441 }
442
443 pad_string = ((char *)p_pad) + pad_desc[index].offset;
444 field_size = pad_desc[index].field_size;
445 /* Ensure null terminator */
446 pad_string[field_size - 1] = 0;
447
448 pad_string_len = strlen(pad_string) + 1;
449
450 if (offset > pad_string_len) {
451 phr->error = HPI_ERROR_INVALID_CONTROL_VALUE;
452 break;
453 }
454
455 tocopy = pad_string_len - offset;
456 if (tocopy > sizeof(phr->u.cu.chars8.sz_data))
457 tocopy = sizeof(phr->u.cu.chars8.sz_data);
458
459 HPI_DEBUG_LOG(VERBOSE,
460 "PADS memcpy(%d), offset %d \n", tocopy,
461 offset);
462 memcpy(phr->u.cu.chars8.sz_data, &pad_string[offset],
463 tocopy);
464
465 phr->u.cu.chars8.remaining_chars =
466 pad_string_len - offset - tocopy;
467 }
468 break;
469 default:
470 found = 0;
471 break;
472 }
473
474 if (found)
475 HPI_DEBUG_LOG(VERBOSE,
476 "cached adap %d, ctl %d, type %d, attr %d\n",
477 phm->adapter_index, pI->control_index,
478 pI->control_type, phm->u.c.attribute);
479 else
480 HPI_DEBUG_LOG(VERBOSE,
481 "uncached adap %d, ctl %d, ctl type %d\n",
482 phm->adapter_index, pI->control_index,
483 pI->control_type);
484
485 if (found)
486 phr->size =
487 sizeof(struct hpi_response_header) +
488 sizeof(struct hpi_control_res);
489
490 return found;
491}
492
493/** Updates the cache with Set values.
494
495Only update if no error.
496Volume and Level return the limited values in the response, so use these
497Multiplexer does so use sent values
498*/
499void hpi_sync_control_cache(struct hpi_control_cache *p_cache,
500 struct hpi_message *phm, struct hpi_response *phr)
501{
502 u16 control_index;
503 struct hpi_control_cache_single *pC;
504 struct hpi_control_cache_info *pI;
505
506 if (!find_control(phm, p_cache, &pI, &control_index))
507 return;
508
509 /* pC is the default cached control strucure.
510 May be cast to something else in the following switch statement.
511 */
512 pC = (struct hpi_control_cache_single *)pI;
513
514 switch (pI->control_type) {
515 case HPI_CONTROL_VOLUME:
516 if (phm->u.c.attribute == HPI_VOLUME_GAIN) {
517 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
518 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
519 }
520 break;
521 case HPI_CONTROL_MULTIPLEXER:
522 /* mux does not return its setting on Set command. */
523 if (phr->error)
524 return;
525 if (phm->u.c.attribute == HPI_MULTIPLEXER_SOURCE) {
526 pC->u.x.source_node_type = (u16)phm->u.c.param1;
527 pC->u.x.source_node_index = (u16)phm->u.c.param2;
528 }
529 break;
530 case HPI_CONTROL_CHANNEL_MODE:
531 /* mode does not return its setting on Set command. */
532 if (phr->error)
533 return;
534 if (phm->u.c.attribute == HPI_CHANNEL_MODE_MODE)
535 pC->u.m.mode = (u16)phm->u.c.param1;
536 break;
537 case HPI_CONTROL_LEVEL:
538 if (phm->u.c.attribute == HPI_LEVEL_GAIN) {
539 pC->u.v.an_log[0] = phr->u.c.an_log_value[0];
540 pC->u.v.an_log[1] = phr->u.c.an_log_value[1];
541 }
542 break;
543 case HPI_CONTROL_MICROPHONE:
544 if (phm->u.c.attribute == HPI_MICROPHONE_PHANTOM_POWER)
545 pC->u.phantom_power.state = (u16)phm->u.c.param1;
546 break;
547 case HPI_CONTROL_AESEBU_TRANSMITTER:
548 if (phr->error)
549 return;
550 if (phm->u.c.attribute == HPI_AESEBUTX_FORMAT)
551 pC->u.aes3tx.format = phm->u.c.param1;
552 break;
553 case HPI_CONTROL_AESEBU_RECEIVER:
554 if (phr->error)
555 return;
556 if (phm->u.c.attribute == HPI_AESEBURX_FORMAT)
557 pC->u.aes3rx.source = phm->u.c.param1;
558 break;
559 case HPI_CONTROL_SAMPLECLOCK:
560 if (phr->error)
561 return;
562 if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE)
563 pC->u.clk.source = (u16)phm->u.c.param1;
564 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SOURCE_INDEX)
565 pC->u.clk.source_index = (u16)phm->u.c.param1;
566 else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)
567 pC->u.clk.sample_rate = phm->u.c.param1;
568 break;
569 default:
570 break;
571 }
572}
573
574struct hpi_control_cache *hpi_alloc_control_cache(const u32
575 number_of_controls, const u32 size_in_bytes,
576 struct hpi_control_cache_info *pDSP_control_buffer)
577{
578 struct hpi_control_cache *p_cache =
579 kmalloc(sizeof(*p_cache), GFP_KERNEL);
580 p_cache->cache_size_in_bytes = size_in_bytes;
581 p_cache->control_count = number_of_controls;
582 p_cache->p_cache =
583 (struct hpi_control_cache_single *)pDSP_control_buffer;
584 p_cache->init = 0;
585 p_cache->p_info =
586 kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count,
587 GFP_KERNEL);
588 return p_cache;
589}
590
591void hpi_free_control_cache(struct hpi_control_cache *p_cache)
592{
593 if ((p_cache->init) && (p_cache->p_info)) {
594 kfree(p_cache->p_info);
595 p_cache->p_info = NULL;
596 p_cache->init = 0;
597 kfree(p_cache);
598 }
599}
600
601static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
602{
603
604 switch (phm->function) {
605 case HPI_SUBSYS_OPEN:
606 case HPI_SUBSYS_CLOSE:
607 case HPI_SUBSYS_DRIVER_UNLOAD:
608 phr->error = 0;
609 break;
610 case HPI_SUBSYS_DRIVER_LOAD:
611 wipe_adapter_list();
612 hpios_alistlock_init(&adapters);
613 phr->error = 0;
614 break;
615 case HPI_SUBSYS_GET_INFO:
616 subsys_get_adapters(phr);
617 break;
618 case HPI_SUBSYS_CREATE_ADAPTER:
619 case HPI_SUBSYS_DELETE_ADAPTER:
620 phr->error = 0;
621 break;
622 default:
623 phr->error = HPI_ERROR_INVALID_FUNC;
624 break;
625 }
626}
627
628void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
629{
630 switch (phm->type) {
631 case HPI_TYPE_MESSAGE:
632 switch (phm->object) {
633 case HPI_OBJ_SUBSYSTEM:
634 subsys_message(phm, phr);
635 break;
636 }
637 break;
638
639 default:
640 phr->error = HPI_ERROR_INVALID_TYPE;
641 break;
642 }
643}
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h
new file mode 100644
index 000000000000..6229022f56cb
--- /dev/null
+++ b/sound/pci/asihpi/hpicmn.h
@@ -0,0 +1,64 @@
1/**
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19*/
20
21struct hpi_adapter_obj {
22 struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */
23 u16 adapter_type; /* ASI6701 etc */
24 u16 index; /* */
25 u16 open; /* =1 when adapter open */
26 u16 mixer_open;
27
28 struct hpios_spinlock dsp_lock;
29
30 u16 dsp_crashed;
31 u16 has_control_cache;
32 void *priv;
33};
34
35struct hpi_control_cache {
36 u32 init; /**< indicates whether the
37 structures are initialized */
38 u32 control_count;
39 u32 cache_size_in_bytes;
40 struct hpi_control_cache_info
41 **p_info; /**< pointer to allocated memory of
42 lookup pointers. */
43 struct hpi_control_cache_single
44 *p_cache; /**< pointer to DSP's control cache. */
45};
46
47struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index);
48u16 hpi_add_adapter(struct hpi_adapter_obj *pao);
49
50void hpi_delete_adapter(struct hpi_adapter_obj *pao);
51
52short hpi_check_control_cache(struct hpi_control_cache *pC,
53 struct hpi_message *phm, struct hpi_response *phr);
54struct hpi_control_cache *hpi_alloc_control_cache(const u32
55 number_of_controls, const u32 size_in_bytes,
56 struct hpi_control_cache_info
57 *pDSP_control_buffer);
58void hpi_free_control_cache(struct hpi_control_cache *p_cache);
59
60void hpi_sync_control_cache(struct hpi_control_cache *pC,
61 struct hpi_message *phm, struct hpi_response *phr);
62u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
63short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
64 struct hpi_message *phm, void **p, unsigned int *pN);
diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c
new file mode 100644
index 000000000000..4cd85a401b34
--- /dev/null
+++ b/sound/pci/asihpi/hpidebug.c
@@ -0,0 +1,225 @@
1/************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Debug macro translation.
20
21************************************************************************/
22
23#include "hpi_internal.h"
24#include "hpidebug.h"
25
26/* Debug level; 0 quiet; 1 informative, 2 debug, 3 verbose debug. */
27int hpi_debug_level = HPI_DEBUG_LEVEL_DEFAULT;
28
29void hpi_debug_init(void)
30{
31 printk(KERN_INFO "debug start\n");
32}
33
34int hpi_debug_level_set(int level)
35{
36 int old_level;
37
38 old_level = hpi_debug_level;
39 hpi_debug_level = level;
40 return old_level;
41}
42
43int hpi_debug_level_get(void)
44{
45 return hpi_debug_level;
46}
47
48#ifdef HPIOS_DEBUG_PRINT
49/* implies OS has no printf-like function */
50#include <stdarg.h>
51
52void hpi_debug_printf(char *fmt, ...)
53{
54 va_list arglist;
55 char buffer[128];
56
57 va_start(arglist, fmt);
58
59 if (buffer[0])
60 HPIOS_DEBUG_PRINT(buffer);
61 va_end(arglist);
62}
63#endif
64
65struct treenode {
66 void *array;
67 unsigned int num_elements;
68};
69
70#define make_treenode_from_array(nodename, array) \
71static void *tmp_strarray_##nodename[] = array; \
72static struct treenode nodename = { \
73 &tmp_strarray_##nodename, \
74 ARRAY_SIZE(tmp_strarray_##nodename) \
75};
76
77#define get_treenode_elem(node_ptr, idx, type) \
78 (&(*((type *)(node_ptr)->array)[idx]))
79
80make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS)
81
82 make_treenode_from_array(hpi_subsys_strings, HPI_SUBSYS_STRINGS)
83 make_treenode_from_array(hpi_adapter_strings, HPI_ADAPTER_STRINGS)
84 make_treenode_from_array(hpi_istream_strings, HPI_ISTREAM_STRINGS)
85 make_treenode_from_array(hpi_ostream_strings, HPI_OSTREAM_STRINGS)
86 make_treenode_from_array(hpi_mixer_strings, HPI_MIXER_STRINGS)
87 make_treenode_from_array(hpi_node_strings,
88 {
89 "NODE is invalid object"})
90
91 make_treenode_from_array(hpi_control_strings, HPI_CONTROL_STRINGS)
92 make_treenode_from_array(hpi_nvmemory_strings, HPI_OBJ_STRINGS)
93 make_treenode_from_array(hpi_digitalio_strings, HPI_DIGITALIO_STRINGS)
94 make_treenode_from_array(hpi_watchdog_strings, HPI_WATCHDOG_STRINGS)
95 make_treenode_from_array(hpi_clock_strings, HPI_CLOCK_STRINGS)
96 make_treenode_from_array(hpi_profile_strings, HPI_PROFILE_STRINGS)
97 make_treenode_from_array(hpi_asyncevent_strings, HPI_ASYNCEVENT_STRINGS)
98#define HPI_FUNCTION_STRINGS \
99{ \
100 &hpi_subsys_strings,\
101 &hpi_adapter_strings,\
102 &hpi_ostream_strings,\
103 &hpi_istream_strings,\
104 &hpi_mixer_strings,\
105 &hpi_node_strings,\
106 &hpi_control_strings,\
107 &hpi_nvmemory_strings,\
108 &hpi_digitalio_strings,\
109 &hpi_watchdog_strings,\
110 &hpi_clock_strings,\
111 &hpi_profile_strings,\
112 &hpi_control_strings, \
113 &hpi_asyncevent_strings \
114};
115 make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS)
116
117 compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match);
118
119static char *hpi_function_string(unsigned int function)
120{
121 unsigned int object;
122 struct treenode *tmp;
123
124 object = function / HPI_OBJ_FUNCTION_SPACING;
125 function = function - object * HPI_OBJ_FUNCTION_SPACING;
126
127 if (object == 0 || object == HPI_OBJ_NODE
128 || object > hpi_function_strings.num_elements)
129 return "invalid object";
130
131 tmp = get_treenode_elem(&hpi_function_strings, object - 1,
132 struct treenode *);
133
134 if (function == 0 || function > tmp->num_elements)
135 return "invalid function";
136
137 return get_treenode_elem(tmp, function - 1, char *);
138}
139
140void hpi_debug_message(struct hpi_message *phm, char *sz_fileline)
141{
142 if (phm) {
143 if ((phm->object <= HPI_OBJ_MAXINDEX) && phm->object) {
144 u16 index = 0;
145 u16 attrib = 0;
146 int is_control = 0;
147
148 index = phm->obj_index;
149 switch (phm->object) {
150 case HPI_OBJ_ADAPTER:
151 case HPI_OBJ_PROFILE:
152 break;
153 case HPI_OBJ_MIXER:
154 if (phm->function ==
155 HPI_MIXER_GET_CONTROL_BY_INDEX)
156 index = phm->u.m.control_index;
157 break;
158 case HPI_OBJ_OSTREAM:
159 case HPI_OBJ_ISTREAM:
160 break;
161
162 case HPI_OBJ_CONTROLEX:
163 case HPI_OBJ_CONTROL:
164 if (phm->version == 1)
165 attrib = HPI_CTL_ATTR(UNIVERSAL, 1);
166 else
167 attrib = phm->u.c.attribute;
168 is_control = 1;
169 break;
170 default:
171 break;
172 }
173
174 if (is_control && (attrib & 0xFF00)) {
175 int control_type = (attrib & 0xFF00) >> 8;
176 int attr_index = HPI_CTL_ATTR_INDEX(attrib);
177 /* note the KERN facility level
178 is in szFileline already */
179 printk("%s adapter %d %s "
180 "ctrl_index x%04x %s %d\n",
181 sz_fileline, phm->adapter_index,
182 hpi_function_string(phm->function),
183 index,
184 get_treenode_elem
185 (&hpi_control_type_strings,
186 control_type, char *),
187 attr_index);
188
189 } else
190 printk("%s adapter %d %s "
191 "idx x%04x attr x%04x \n",
192 sz_fileline, phm->adapter_index,
193 hpi_function_string(phm->function),
194 index, attrib);
195 } else {
196 printk("adap=%d, invalid obj=%d, func=0x%x\n",
197 phm->adapter_index, phm->object,
198 phm->function);
199 }
200 } else
201 printk(KERN_ERR
202 "NULL message pointer to hpi_debug_message!\n");
203}
204
205void hpi_debug_data(u16 *pdata, u32 len)
206{
207 u32 i;
208 int j;
209 int k;
210 int lines;
211 int cols = 8;
212
213 lines = (len + cols - 1) / cols;
214 if (lines > 8)
215 lines = 8;
216
217 for (i = 0, j = 0; j < lines; j++) {
218 printk(KERN_DEBUG "%p:", (pdata + i));
219
220 for (k = 0; k < cols && i < len; i++, k++)
221 printk("%s%04x", k == 0 ? "" : " ", pdata[i]);
222
223 printk("\n");
224 }
225}
diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h
new file mode 100644
index 000000000000..44dccadcc25b
--- /dev/null
+++ b/sound/pci/asihpi/hpidebug.h
@@ -0,0 +1,385 @@
1/*****************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Debug macros.
20
21*****************************************************************************/
22
23#ifndef _HPIDEBUG_H
24#define _HPIDEBUG_H
25
26#include "hpi_internal.h"
27
28/* Define debugging levels. */
29enum { HPI_DEBUG_LEVEL_ERROR = 0, /* always log errors */
30 HPI_DEBUG_LEVEL_WARNING = 1,
31 HPI_DEBUG_LEVEL_NOTICE = 2,
32 HPI_DEBUG_LEVEL_INFO = 3,
33 HPI_DEBUG_LEVEL_DEBUG = 4,
34 HPI_DEBUG_LEVEL_VERBOSE = 5 /* same printk level as DEBUG */
35};
36
37#define HPI_DEBUG_LEVEL_DEFAULT HPI_DEBUG_LEVEL_NOTICE
38
39/* an OS can define an extra flag string that is appended to
40 the start of each message, eg see hpios_linux.h */
41
42#ifdef SOURCEFILE_NAME
43#define FILE_LINE SOURCEFILE_NAME ":" __stringify(__LINE__) " "
44#else
45#define FILE_LINE __FILE__ ":" __stringify(__LINE__) " "
46#endif
47
48#if defined(HPI_DEBUG) && defined(_WINDOWS)
49#define HPI_DEBUGBREAK() debug_break()
50#else
51#define HPI_DEBUGBREAK()
52#endif
53
54#define HPI_DEBUG_ASSERT(expression) \
55 do { \
56 if (!(expression)) {\
57 printk(KERN_ERR FILE_LINE\
58 "ASSERT " __stringify(expression));\
59 HPI_DEBUGBREAK();\
60 } \
61 } while (0)
62
63#define HPI_DEBUG_LOG(level, ...) \
64 do { \
65 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
66 printk(HPI_DEBUG_FLAG_##level \
67 FILE_LINE __VA_ARGS__); \
68 } \
69 } while (0)
70
71void hpi_debug_init(void);
72int hpi_debug_level_set(int level);
73int hpi_debug_level_get(void);
74/* needed by Linux driver for dynamic debug level changes */
75extern int hpi_debug_level;
76
77void hpi_debug_message(struct hpi_message *phm, char *sz_fileline);
78
79void hpi_debug_data(u16 *pdata, u32 len);
80
81#define HPI_DEBUG_DATA(pdata, len) \
82 do { \
83 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
84 hpi_debug_data(pdata, len); \
85 } while (0)
86
87#define HPI_DEBUG_MESSAGE(level, phm) \
88 do { \
89 if (hpi_debug_level >= HPI_DEBUG_LEVEL_##level) { \
90 hpi_debug_message(phm,HPI_DEBUG_FLAG_##level \
91 FILE_LINE __stringify(level));\
92 } \
93 } while (0)
94
95#define HPI_DEBUG_RESPONSE(phr) \
96 do { \
97 if ((hpi_debug_level >= HPI_DEBUG_LEVEL_DEBUG) && (phr->error))\
98 HPI_DEBUG_LOG(ERROR, \
99 "HPI response - error# %d\n", \
100 phr->error); \
101 else if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE) \
102 HPI_DEBUG_LOG(VERBOSE, "HPI response OK\n");\
103 } while (0)
104
105#ifndef compile_time_assert
106#define compile_time_assert(cond, msg) \
107 typedef char msg[(cond) ? 1 : -1]
108#endif
109
110 /* check that size is exactly some number */
111#define function_count_check(sym, size) \
112 compile_time_assert((sym##_FUNCTION_COUNT) == (size),\
113 strings_match_defs_##sym)
114
115/* These strings should be generated using a macro which defines
116 the corresponding symbol values. */
117#define HPI_OBJ_STRINGS \
118{ \
119 "HPI_OBJ_SUBSYSTEM", \
120 "HPI_OBJ_ADAPTER", \
121 "HPI_OBJ_OSTREAM", \
122 "HPI_OBJ_ISTREAM", \
123 "HPI_OBJ_MIXER", \
124 "HPI_OBJ_NODE", \
125 "HPI_OBJ_CONTROL", \
126 "HPI_OBJ_NVMEMORY", \
127 "HPI_OBJ_DIGITALIO", \
128 "HPI_OBJ_WATCHDOG", \
129 "HPI_OBJ_CLOCK", \
130 "HPI_OBJ_PROFILE", \
131 "HPI_OBJ_CONTROLEX" \
132}
133
134#define HPI_SUBSYS_STRINGS \
135{ \
136 "HPI_SUBSYS_OPEN", \
137 "HPI_SUBSYS_GET_VERSION", \
138 "HPI_SUBSYS_GET_INFO", \
139 "HPI_SUBSYS_FIND_ADAPTERS", \
140 "HPI_SUBSYS_CREATE_ADAPTER",\
141 "HPI_SUBSYS_CLOSE", \
142 "HPI_SUBSYS_DELETE_ADAPTER", \
143 "HPI_SUBSYS_DRIVER_LOAD", \
144 "HPI_SUBSYS_DRIVER_UNLOAD", \
145 "HPI_SUBSYS_READ_PORT_8", \
146 "HPI_SUBSYS_WRITE_PORT_8", \
147 "HPI_SUBSYS_GET_NUM_ADAPTERS",\
148 "HPI_SUBSYS_GET_ADAPTER", \
149 "HPI_SUBSYS_SET_NETWORK_INTERFACE"\
150}
151function_count_check(HPI_SUBSYS, 14);
152
153#define HPI_ADAPTER_STRINGS \
154{ \
155 "HPI_ADAPTER_OPEN", \
156 "HPI_ADAPTER_CLOSE", \
157 "HPI_ADAPTER_GET_INFO", \
158 "HPI_ADAPTER_GET_ASSERT", \
159 "HPI_ADAPTER_TEST_ASSERT", \
160 "HPI_ADAPTER_SET_MODE", \
161 "HPI_ADAPTER_GET_MODE", \
162 "HPI_ADAPTER_ENABLE_CAPABILITY",\
163 "HPI_ADAPTER_SELFTEST", \
164 "HPI_ADAPTER_FIND_OBJECT", \
165 "HPI_ADAPTER_QUERY_FLASH", \
166 "HPI_ADAPTER_START_FLASH", \
167 "HPI_ADAPTER_PROGRAM_FLASH", \
168 "HPI_ADAPTER_SET_PROPERTY", \
169 "HPI_ADAPTER_GET_PROPERTY", \
170 "HPI_ADAPTER_ENUM_PROPERTY", \
171 "HPI_ADAPTER_MODULE_INFO", \
172 "HPI_ADAPTER_DEBUG_READ" \
173}
174
175function_count_check(HPI_ADAPTER, 18);
176
177#define HPI_OSTREAM_STRINGS \
178{ \
179 "HPI_OSTREAM_OPEN", \
180 "HPI_OSTREAM_CLOSE", \
181 "HPI_OSTREAM_WRITE", \
182 "HPI_OSTREAM_START", \
183 "HPI_OSTREAM_STOP", \
184 "HPI_OSTREAM_RESET", \
185 "HPI_OSTREAM_GET_INFO", \
186 "HPI_OSTREAM_QUERY_FORMAT", \
187 "HPI_OSTREAM_DATA", \
188 "HPI_OSTREAM_SET_VELOCITY", \
189 "HPI_OSTREAM_SET_PUNCHINOUT", \
190 "HPI_OSTREAM_SINEGEN", \
191 "HPI_OSTREAM_ANC_RESET", \
192 "HPI_OSTREAM_ANC_GET_INFO", \
193 "HPI_OSTREAM_ANC_READ", \
194 "HPI_OSTREAM_SET_TIMESCALE",\
195 "HPI_OSTREAM_SET_FORMAT", \
196 "HPI_OSTREAM_HOSTBUFFER_ALLOC", \
197 "HPI_OSTREAM_HOSTBUFFER_FREE", \
198 "HPI_OSTREAM_GROUP_ADD",\
199 "HPI_OSTREAM_GROUP_GETMAP", \
200 "HPI_OSTREAM_GROUP_RESET", \
201 "HPI_OSTREAM_HOSTBUFFER_GET_INFO", \
202 "HPI_OSTREAM_WAIT_START", \
203}
204function_count_check(HPI_OSTREAM, 24);
205
206#define HPI_ISTREAM_STRINGS \
207{ \
208 "HPI_ISTREAM_OPEN", \
209 "HPI_ISTREAM_CLOSE", \
210 "HPI_ISTREAM_SET_FORMAT", \
211 "HPI_ISTREAM_READ", \
212 "HPI_ISTREAM_START", \
213 "HPI_ISTREAM_STOP", \
214 "HPI_ISTREAM_RESET", \
215 "HPI_ISTREAM_GET_INFO", \
216 "HPI_ISTREAM_QUERY_FORMAT", \
217 "HPI_ISTREAM_ANC_RESET", \
218 "HPI_ISTREAM_ANC_GET_INFO", \
219 "HPI_ISTREAM_ANC_WRITE", \
220 "HPI_ISTREAM_HOSTBUFFER_ALLOC",\
221 "HPI_ISTREAM_HOSTBUFFER_FREE", \
222 "HPI_ISTREAM_GROUP_ADD", \
223 "HPI_ISTREAM_GROUP_GETMAP", \
224 "HPI_ISTREAM_GROUP_RESET", \
225 "HPI_ISTREAM_HOSTBUFFER_GET_INFO", \
226 "HPI_ISTREAM_WAIT_START", \
227}
228function_count_check(HPI_ISTREAM, 19);
229
230#define HPI_MIXER_STRINGS \
231{ \
232 "HPI_MIXER_OPEN", \
233 "HPI_MIXER_CLOSE", \
234 "HPI_MIXER_GET_INFO", \
235 "HPI_MIXER_GET_NODE_INFO", \
236 "HPI_MIXER_GET_CONTROL", \
237 "HPI_MIXER_SET_CONNECTION", \
238 "HPI_MIXER_GET_CONNECTIONS", \
239 "HPI_MIXER_GET_CONTROL_BY_INDEX", \
240 "HPI_MIXER_GET_CONTROL_ARRAY_BY_INDEX", \
241 "HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES", \
242 "HPI_MIXER_STORE", \
243}
244function_count_check(HPI_MIXER, 11);
245
246#define HPI_CONTROL_STRINGS \
247{ \
248 "HPI_CONTROL_GET_INFO", \
249 "HPI_CONTROL_GET_STATE", \
250 "HPI_CONTROL_SET_STATE" \
251}
252function_count_check(HPI_CONTROL, 3);
253
254#define HPI_NVMEMORY_STRINGS \
255{ \
256 "HPI_NVMEMORY_OPEN", \
257 "HPI_NVMEMORY_READ_BYTE", \
258 "HPI_NVMEMORY_WRITE_BYTE" \
259}
260function_count_check(HPI_NVMEMORY, 3);
261
262#define HPI_DIGITALIO_STRINGS \
263{ \
264 "HPI_GPIO_OPEN", \
265 "HPI_GPIO_READ_BIT", \
266 "HPI_GPIO_WRITE_BIT", \
267 "HPI_GPIO_READ_ALL", \
268 "HPI_GPIO_WRITE_STATUS"\
269}
270function_count_check(HPI_GPIO, 5);
271
272#define HPI_WATCHDOG_STRINGS \
273{ \
274 "HPI_WATCHDOG_OPEN", \
275 "HPI_WATCHDOG_SET_TIME", \
276 "HPI_WATCHDOG_PING" \
277}
278
279#define HPI_CLOCK_STRINGS \
280{ \
281 "HPI_CLOCK_OPEN", \
282 "HPI_CLOCK_SET_TIME", \
283 "HPI_CLOCK_GET_TIME" \
284}
285
286#define HPI_PROFILE_STRINGS \
287{ \
288 "HPI_PROFILE_OPEN_ALL", \
289 "HPI_PROFILE_START_ALL", \
290 "HPI_PROFILE_STOP_ALL", \
291 "HPI_PROFILE_GET", \
292 "HPI_PROFILE_GET_IDLECOUNT", \
293 "HPI_PROFILE_GET_NAME", \
294 "HPI_PROFILE_GET_UTILIZATION" \
295}
296function_count_check(HPI_PROFILE, 7);
297
298#define HPI_ASYNCEVENT_STRINGS \
299{ \
300 "HPI_ASYNCEVENT_OPEN",\
301 "HPI_ASYNCEVENT_CLOSE ",\
302 "HPI_ASYNCEVENT_WAIT",\
303 "HPI_ASYNCEVENT_GETCOUNT",\
304 "HPI_ASYNCEVENT_GET",\
305 "HPI_ASYNCEVENT_SENDEVENTS"\
306}
307function_count_check(HPI_ASYNCEVENT, 6);
308
309#define HPI_CONTROL_TYPE_STRINGS \
310{ \
311 "null control", \
312 "HPI_CONTROL_CONNECTION", \
313 "HPI_CONTROL_VOLUME", \
314 "HPI_CONTROL_METER", \
315 "HPI_CONTROL_MUTE", \
316 "HPI_CONTROL_MULTIPLEXER", \
317 "HPI_CONTROL_AESEBU_TRANSMITTER", \
318 "HPI_CONTROL_AESEBU_RECEIVER", \
319 "HPI_CONTROL_LEVEL", \
320 "HPI_CONTROL_TUNER", \
321 "HPI_CONTROL_ONOFFSWITCH", \
322 "HPI_CONTROL_VOX", \
323 "HPI_CONTROL_AES18_TRANSMITTER", \
324 "HPI_CONTROL_AES18_RECEIVER", \
325 "HPI_CONTROL_AES18_BLOCKGENERATOR", \
326 "HPI_CONTROL_CHANNEL_MODE", \
327 "HPI_CONTROL_BITSTREAM", \
328 "HPI_CONTROL_SAMPLECLOCK", \
329 "HPI_CONTROL_MICROPHONE", \
330 "HPI_CONTROL_PARAMETRIC_EQ", \
331 "HPI_CONTROL_COMPANDER", \
332 "HPI_CONTROL_COBRANET", \
333 "HPI_CONTROL_TONE_DETECT", \
334 "HPI_CONTROL_SILENCE_DETECT", \
335 "HPI_CONTROL_PAD", \
336 "HPI_CONTROL_SRC" ,\
337 "HPI_CONTROL_UNIVERSAL" \
338}
339
340compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27),
341 controltype_strings_match_defs);
342
343#define HPI_SOURCENODE_STRINGS \
344{ \
345 "no source", \
346 "HPI_SOURCENODE_OSTREAM", \
347 "HPI_SOURCENODE_LINEIN", \
348 "HPI_SOURCENODE_AESEBU_IN", \
349 "HPI_SOURCENODE_TUNER", \
350 "HPI_SOURCENODE_RF", \
351 "HPI_SOURCENODE_CLOCK_SOURCE", \
352 "HPI_SOURCENODE_RAW_BITSTREAM", \
353 "HPI_SOURCENODE_MICROPHONE", \
354 "HPI_SOURCENODE_COBRANET", \
355 "HPI_SOURCENODE_ANALOG", \
356 "HPI_SOURCENODE_ADAPTER" \
357}
358
359compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) ==
360 (12), sourcenode_strings_match_defs);
361
362#define HPI_DESTNODE_STRINGS \
363{ \
364 "no destination", \
365 "HPI_DESTNODE_ISTREAM", \
366 "HPI_DESTNODE_LINEOUT", \
367 "HPI_DESTNODE_AESEBU_OUT", \
368 "HPI_DESTNODE_RF", \
369 "HPI_DESTNODE_SPEAKER", \
370 "HPI_DESTNODE_COBRANET", \
371 "HPI_DESTNODE_ANALOG" \
372}
373compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_BASE + 1) == (8),
374 destnode_strings_match_defs);
375
376#define HPI_CONTROL_CHANNEL_MODE_STRINGS \
377{ \
378 "XXX HPI_CHANNEL_MODE_ERROR XXX", \
379 "HPI_CHANNEL_MODE_NORMAL", \
380 "HPI_CHANNEL_MODE_SWAP", \
381 "HPI_CHANNEL_MODE_LEFT_ONLY", \
382 "HPI_CHANNEL_MODE_RIGHT_ONLY" \
383}
384
385#endif /* _HPIDEBUG_H */
diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c
new file mode 100644
index 000000000000..9b10d9a5c255
--- /dev/null
+++ b/sound/pci/asihpi/hpidspcd.c
@@ -0,0 +1,172 @@
1/***********************************************************************/
2/*!
3
4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation;
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20\file
21Functions for reading DSP code to load into DSP
22
23(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using
24hotplug firmware loader from individual dsp code files
25
26If neither of the above is defined, code is read from linked arrays.
27DSPCODE_ARRAY is defined.
28
29HPI_INCLUDE_**** must be defined
30and the appropriate hzz?????.c or hex?????.c linked in
31
32 */
33/***********************************************************************/
34#define SOURCEFILE_NAME "hpidspcd.c"
35#include "hpidspcd.h"
36#include "hpidebug.h"
37
38/**
39 Header structure for binary dsp code file (see asidsp.doc)
40 This structure must match that used in s2bin.c for generation of asidsp.bin
41 */
42
43#ifndef DISABLE_PRAGMA_PACK1
44#pragma pack(push, 1)
45#endif
46
47struct code_header {
48 u32 size;
49 char type[4];
50 u32 adapter;
51 u32 version;
52 u32 crc;
53};
54
55#ifndef DISABLE_PRAGMA_PACK1
56#pragma pack(pop)
57#endif
58
59#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
60 HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
61
62/***********************************************************************/
63#include "linux/pci.h"
64/*-------------------------------------------------------------------*/
65short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
66 u32 *pos_error_code)
67{
68 const struct firmware *ps_firmware = ps_dsp_code->ps_firmware;
69 struct code_header header;
70 char fw_name[20];
71 int err;
72
73 sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
74 HPI_DEBUG_LOG(INFO, "requesting firmware for %s\n", fw_name);
75
76 err = request_firmware(&ps_firmware, fw_name,
77 &ps_dsp_code->ps_dev->dev);
78 if (err != 0) {
79 HPI_DEBUG_LOG(ERROR, "%d, request_firmware failed for %s\n",
80 err, fw_name);
81 goto error1;
82 }
83 if (ps_firmware->size < sizeof(header)) {
84 HPI_DEBUG_LOG(ERROR, "header size too small %s\n", fw_name);
85 goto error2;
86 }
87 memcpy(&header, ps_firmware->data, sizeof(header));
88 if (header.adapter != adapter) {
89 HPI_DEBUG_LOG(ERROR, "adapter type incorrect %4x != %4x\n",
90 header.adapter, adapter);
91 goto error2;
92 }
93 if (header.size != ps_firmware->size) {
94 HPI_DEBUG_LOG(ERROR, "code size wrong %d != %ld\n",
95 header.size, (unsigned long)ps_firmware->size);
96 goto error2;
97 }
98
99 if (header.version / 10000 != HPI_VER_DECIMAL / 10000) {
100 HPI_DEBUG_LOG(ERROR,
101 "firmware major version mismatch "
102 "DSP image %d != driver %d\n", header.version,
103 HPI_VER_DECIMAL);
104 goto error2;
105 }
106
107 if (header.version != HPI_VER_DECIMAL) {
108 HPI_DEBUG_LOG(WARNING,
109 "version mismatch DSP image %d != driver %d\n",
110 header.version, HPI_VER_DECIMAL);
111 /* goto error2; still allow driver to load */
112 }
113
114 HPI_DEBUG_LOG(INFO, "dsp code %s opened\n", fw_name);
115 ps_dsp_code->ps_firmware = ps_firmware;
116 ps_dsp_code->block_length = header.size / sizeof(u32);
117 ps_dsp_code->word_count = sizeof(header) / sizeof(u32);
118 ps_dsp_code->version = header.version;
119 ps_dsp_code->crc = header.crc;
120 return 0;
121
122error2:
123 release_firmware(ps_firmware);
124error1:
125 ps_dsp_code->ps_firmware = NULL;
126 ps_dsp_code->block_length = 0;
127 return HPI_ERROR_DSP_FILE_NOT_FOUND;
128}
129
130/*-------------------------------------------------------------------*/
131void hpi_dsp_code_close(struct dsp_code *ps_dsp_code)
132{
133 if (ps_dsp_code->ps_firmware != NULL) {
134 HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
135 release_firmware(ps_dsp_code->ps_firmware);
136 ps_dsp_code->ps_firmware = NULL;
137 }
138}
139
140/*-------------------------------------------------------------------*/
141void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code)
142{
143 /* Go back to start of data, after header */
144 ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
145}
146
147/*-------------------------------------------------------------------*/
148short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword)
149{
150 if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length)
151 return (HPI_ERROR_DSP_FILE_FORMAT);
152
153 *pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code->
154 word_count];
155 ps_dsp_code->word_count++;
156 return 0;
157}
158
159/*-------------------------------------------------------------------*/
160short hpi_dsp_code_read_block(size_t words_requested,
161 struct dsp_code *ps_dsp_code, u32 **ppblock)
162{
163 if (ps_dsp_code->word_count + words_requested >
164 ps_dsp_code->block_length)
165 return HPI_ERROR_DSP_FILE_FORMAT;
166
167 *ppblock =
168 ((u32 *)(ps_dsp_code->ps_firmware->data)) +
169 ps_dsp_code->word_count;
170 ps_dsp_code->word_count += words_requested;
171 return 0;
172}
diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h
new file mode 100644
index 000000000000..d7c240398225
--- /dev/null
+++ b/sound/pci/asihpi/hpidspcd.h
@@ -0,0 +1,104 @@
1/***********************************************************************/
2/**
3
4 AudioScience HPI driver
5 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation;
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20\file
21Functions for reading DSP code to load into DSP
22
23 hpi_dspcode_defines HPI DSP code loading method
24Define exactly one of these to select how the DSP code is supplied to
25the adapter.
26
27End users writing applications that use the HPI interface do not have to
28use any of the below defines; they are only necessary for building drivers
29
30HPI_DSPCODE_FILE:
31DSP code is supplied as a file that is opened and read from by the driver.
32
33HPI_DSPCODE_FIRMWARE:
34DSP code is read using the hotplug firmware loader module.
35 Only valid when compiling the HPI kernel driver under Linux.
36*/
37/***********************************************************************/
38#ifndef _HPIDSPCD_H_
39#define _HPIDSPCD_H_
40
41#include "hpi_internal.h"
42
43#ifndef DISABLE_PRAGMA_PACK1
44#pragma pack(push, 1)
45#endif
46
47/** Descriptor for dspcode from firmware loader */
48struct dsp_code {
49 /** Firmware descriptor */
50 const struct firmware *ps_firmware;
51 struct pci_dev *ps_dev;
52 /** Expected number of words in the whole dsp code,INCL header */
53 long int block_length;
54 /** Number of words read so far */
55 long int word_count;
56 /** Version read from dsp code file */
57 u32 version;
58 /** CRC read from dsp code file */
59 u32 crc;
60};
61
62#ifndef DISABLE_PRAGMA_PACK1
63#pragma pack(pop)
64#endif
65
66/** Prepare *psDspCode to refer to the requuested adapter.
67 Searches the file, or selects the appropriate linked array
68
69\return 0 for success, or error code if requested code is not available
70*/
71short hpi_dsp_code_open(
72 /** Code identifier, usually adapter family */
73 u32 adapter,
74 /** Pointer to DSP code control structure */
75 struct dsp_code *ps_dsp_code,
76 /** Pointer to dword to receive OS specific error code */
77 u32 *pos_error_code);
78
79/** Close the DSP code file */
80void hpi_dsp_code_close(struct dsp_code *ps_dsp_code);
81
82/** Rewind to the beginning of the DSP code file (for verify) */
83void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code);
84
85/** Read one word from the dsp code file
86 \return 0 for success, or error code if eof, or block length exceeded
87*/
88short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code,
89 /**< DSP code descriptor */
90 u32 *pword /**< where to store the read word */
91 );
92
93/** Get a block of dsp code into an internal buffer, and provide a pointer to
94that buffer. (If dsp code is already an array in memory, it is referenced,
95not copied.)
96
97\return Error if requested number of words are not available
98*/
99short hpi_dsp_code_read_block(size_t words_requested,
100 struct dsp_code *ps_dsp_code,
101 /* Pointer to store (Pointer to code buffer) */
102 u32 **ppblock);
103
104#endif
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
new file mode 100644
index 000000000000..eda26b312324
--- /dev/null
+++ b/sound/pci/asihpi/hpifunc.c
@@ -0,0 +1,3864 @@
1
2#include "hpi_internal.h"
3#include "hpimsginit.h"
4
5#include "hpidebug.h"
6
7struct hpi_handle {
8 unsigned int obj_index:12;
9 unsigned int obj_type:4;
10 unsigned int adapter_index:14;
11 unsigned int spare:1;
12 unsigned int read_only:1;
13};
14
15union handle_word {
16 struct hpi_handle h;
17 u32 w;
18};
19
20u32 hpi_indexes_to_handle(const char c_object, const u16 adapter_index,
21 const u16 object_index)
22{
23 union handle_word handle;
24
25 handle.h.adapter_index = adapter_index;
26 handle.h.spare = 0;
27 handle.h.read_only = 0;
28 handle.h.obj_type = c_object;
29 handle.h.obj_index = object_index;
30 return handle.w;
31}
32
33void hpi_handle_to_indexes(const u32 handle, u16 *pw_adapter_index,
34 u16 *pw_object_index)
35{
36 union handle_word uhandle;
37 uhandle.w = handle;
38
39 if (pw_adapter_index)
40 *pw_adapter_index = (u16)uhandle.h.adapter_index;
41 if (pw_object_index)
42 *pw_object_index = (u16)uhandle.h.obj_index;
43}
44
45char hpi_handle_object(const u32 handle)
46{
47 union handle_word uhandle;
48 uhandle.w = handle;
49 return (char)uhandle.h.obj_type;
50}
51
52#define u32TOINDEX(h, i1) \
53do {\
54 if (h == 0) \
55 return HPI_ERROR_INVALID_OBJ; \
56 else \
57 hpi_handle_to_indexes(h, i1, NULL); \
58} while (0)
59
60#define u32TOINDEXES(h, i1, i2) \
61do {\
62 if (h == 0) \
63 return HPI_ERROR_INVALID_OBJ; \
64 else \
65 hpi_handle_to_indexes(h, i1, i2);\
66} while (0)
67
68void hpi_format_to_msg(struct hpi_msg_format *pMF,
69 const struct hpi_format *pF)
70{
71 pMF->sample_rate = pF->sample_rate;
72 pMF->bit_rate = pF->bit_rate;
73 pMF->attributes = pF->attributes;
74 pMF->channels = pF->channels;
75 pMF->format = pF->format;
76}
77
78static void hpi_msg_to_format(struct hpi_format *pF,
79 struct hpi_msg_format *pMF)
80{
81 pF->sample_rate = pMF->sample_rate;
82 pF->bit_rate = pMF->bit_rate;
83 pF->attributes = pMF->attributes;
84 pF->channels = pMF->channels;
85 pF->format = pMF->format;
86 pF->mode_legacy = 0;
87 pF->unused = 0;
88}
89
90void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR)
91{
92 pSR->u.legacy_stream_info.auxiliary_data_available =
93 pSR->u.stream_info.auxiliary_data_available;
94 pSR->u.legacy_stream_info.state = pSR->u.stream_info.state;
95}
96
97static struct hpi_hsubsys gh_subsys;
98
99struct hpi_hsubsys *hpi_subsys_create(void
100 )
101{
102 struct hpi_message hm;
103 struct hpi_response hr;
104
105 memset(&gh_subsys, 0, sizeof(struct hpi_hsubsys));
106
107 {
108 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
109 HPI_SUBSYS_OPEN);
110 hpi_send_recv(&hm, &hr);
111
112 if (hr.error == 0)
113 return &gh_subsys;
114
115 }
116 return NULL;
117}
118
119void hpi_subsys_free(const struct hpi_hsubsys *ph_subsys)
120{
121 struct hpi_message hm;
122 struct hpi_response hr;
123
124 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
125 HPI_SUBSYS_CLOSE);
126 hpi_send_recv(&hm, &hr);
127
128}
129
130u16 hpi_subsys_get_version(const struct hpi_hsubsys *ph_subsys, u32 *pversion)
131{
132 struct hpi_message hm;
133 struct hpi_response hr;
134
135 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
136 HPI_SUBSYS_GET_VERSION);
137 hpi_send_recv(&hm, &hr);
138 *pversion = hr.u.s.version;
139 return hr.error;
140}
141
142u16 hpi_subsys_get_version_ex(const struct hpi_hsubsys *ph_subsys,
143 u32 *pversion_ex)
144{
145 struct hpi_message hm;
146 struct hpi_response hr;
147
148 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
149 HPI_SUBSYS_GET_VERSION);
150 hpi_send_recv(&hm, &hr);
151 *pversion_ex = hr.u.s.data;
152 return hr.error;
153}
154
155u16 hpi_subsys_get_info(const struct hpi_hsubsys *ph_subsys, u32 *pversion,
156 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
157{
158 struct hpi_message hm;
159 struct hpi_response hr;
160 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
161 HPI_SUBSYS_GET_INFO);
162
163 hpi_send_recv(&hm, &hr);
164
165 *pversion = hr.u.s.version;
166 if (list_length > HPI_MAX_ADAPTERS)
167 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
168 HPI_MAX_ADAPTERS);
169 else
170 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list, list_length);
171 *pw_num_adapters = hr.u.s.num_adapters;
172 return hr.error;
173}
174
175u16 hpi_subsys_find_adapters(const struct hpi_hsubsys *ph_subsys,
176 u16 *pw_num_adapters, u16 aw_adapter_list[], u16 list_length)
177{
178 struct hpi_message hm;
179 struct hpi_response hr;
180 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
181 HPI_SUBSYS_FIND_ADAPTERS);
182
183 hpi_send_recv(&hm, &hr);
184
185 if (list_length > HPI_MAX_ADAPTERS) {
186 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
187 HPI_MAX_ADAPTERS * sizeof(u16));
188 memset(&aw_adapter_list[HPI_MAX_ADAPTERS], 0,
189 (list_length - HPI_MAX_ADAPTERS) * sizeof(u16));
190 } else
191 memcpy(aw_adapter_list, &hr.u.s.aw_adapter_list,
192 list_length * sizeof(u16));
193 *pw_num_adapters = hr.u.s.num_adapters;
194
195 return hr.error;
196}
197
198u16 hpi_subsys_create_adapter(const struct hpi_hsubsys *ph_subsys,
199 const struct hpi_resource *p_resource, u16 *pw_adapter_index)
200{
201 struct hpi_message hm;
202 struct hpi_response hr;
203
204 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
205 HPI_SUBSYS_CREATE_ADAPTER);
206 hm.u.s.resource = *p_resource;
207
208 hpi_send_recv(&hm, &hr);
209
210 *pw_adapter_index = hr.u.s.adapter_index;
211 return hr.error;
212}
213
214u16 hpi_subsys_delete_adapter(const struct hpi_hsubsys *ph_subsys,
215 u16 adapter_index)
216{
217 struct hpi_message hm;
218 struct hpi_response hr;
219 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
220 HPI_SUBSYS_DELETE_ADAPTER);
221 hm.adapter_index = adapter_index;
222 hpi_send_recv(&hm, &hr);
223 return hr.error;
224}
225
226u16 hpi_subsys_get_num_adapters(const struct hpi_hsubsys *ph_subsys,
227 int *pn_num_adapters)
228{
229 struct hpi_message hm;
230 struct hpi_response hr;
231 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
232 HPI_SUBSYS_GET_NUM_ADAPTERS);
233 hpi_send_recv(&hm, &hr);
234 *pn_num_adapters = (int)hr.u.s.num_adapters;
235 return hr.error;
236}
237
238u16 hpi_subsys_get_adapter(const struct hpi_hsubsys *ph_subsys, int iterator,
239 u32 *padapter_index, u16 *pw_adapter_type)
240{
241 struct hpi_message hm;
242 struct hpi_response hr;
243 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
244 HPI_SUBSYS_GET_ADAPTER);
245 hm.adapter_index = (u16)iterator;
246 hpi_send_recv(&hm, &hr);
247 *padapter_index = (int)hr.u.s.adapter_index;
248 *pw_adapter_type = hr.u.s.aw_adapter_list[0];
249 return hr.error;
250}
251
252u16 hpi_subsys_set_host_network_interface(const struct hpi_hsubsys *ph_subsys,
253 const char *sz_interface)
254{
255 struct hpi_message hm;
256 struct hpi_response hr;
257 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
258 HPI_SUBSYS_SET_NETWORK_INTERFACE);
259 if (sz_interface == NULL)
260 return HPI_ERROR_INVALID_RESOURCE;
261 hm.u.s.resource.r.net_if = sz_interface;
262 hpi_send_recv(&hm, &hr);
263 return hr.error;
264}
265
266u16 hpi_adapter_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
267{
268 struct hpi_message hm;
269 struct hpi_response hr;
270 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
271 HPI_ADAPTER_OPEN);
272 hm.adapter_index = adapter_index;
273
274 hpi_send_recv(&hm, &hr);
275
276 return hr.error;
277
278}
279
280u16 hpi_adapter_close(const struct hpi_hsubsys *ph_subsys, u16 adapter_index)
281{
282 struct hpi_message hm;
283 struct hpi_response hr;
284 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
285 HPI_ADAPTER_CLOSE);
286 hm.adapter_index = adapter_index;
287
288 hpi_send_recv(&hm, &hr);
289
290 return hr.error;
291}
292
293u16 hpi_adapter_set_mode(const struct hpi_hsubsys *ph_subsys,
294 u16 adapter_index, u32 adapter_mode)
295{
296 return hpi_adapter_set_mode_ex(ph_subsys, adapter_index, adapter_mode,
297 HPI_ADAPTER_MODE_SET);
298}
299
300u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
301 u16 adapter_index, u32 adapter_mode, u16 query_or_set)
302{
303 struct hpi_message hm;
304 struct hpi_response hr;
305 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
306 HPI_ADAPTER_SET_MODE);
307 hm.adapter_index = adapter_index;
308 hm.u.a.adapter_mode = adapter_mode;
309 hm.u.a.assert_id = query_or_set;
310 hpi_send_recv(&hm, &hr);
311 return hr.error;
312}
313
314u16 hpi_adapter_get_mode(const struct hpi_hsubsys *ph_subsys,
315 u16 adapter_index, u32 *padapter_mode)
316{
317 struct hpi_message hm;
318 struct hpi_response hr;
319 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
320 HPI_ADAPTER_GET_MODE);
321 hm.adapter_index = adapter_index;
322 hpi_send_recv(&hm, &hr);
323 if (padapter_mode)
324 *padapter_mode = hr.u.a.serial_number;
325 return hr.error;
326}
327
328u16 hpi_adapter_get_info(const struct hpi_hsubsys *ph_subsys,
329 u16 adapter_index, u16 *pw_num_outstreams, u16 *pw_num_instreams,
330 u16 *pw_version, u32 *pserial_number, u16 *pw_adapter_type)
331{
332 struct hpi_message hm;
333 struct hpi_response hr;
334 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
335 HPI_ADAPTER_GET_INFO);
336 hm.adapter_index = adapter_index;
337
338 hpi_send_recv(&hm, &hr);
339
340 *pw_adapter_type = hr.u.a.adapter_type;
341 *pw_num_outstreams = hr.u.a.num_outstreams;
342 *pw_num_instreams = hr.u.a.num_instreams;
343 *pw_version = hr.u.a.version;
344 *pserial_number = hr.u.a.serial_number;
345 return hr.error;
346}
347
348u16 hpi_adapter_get_module_by_index(const struct hpi_hsubsys *ph_subsys,
349 u16 adapter_index, u16 module_index, u16 *pw_num_outputs,
350 u16 *pw_num_inputs, u16 *pw_version, u32 *pserial_number,
351 u16 *pw_module_type, u32 *ph_module)
352{
353 struct hpi_message hm;
354 struct hpi_response hr;
355
356 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
357 HPI_ADAPTER_MODULE_INFO);
358 hm.adapter_index = adapter_index;
359 hm.u.ax.module_info.index = module_index;
360
361 hpi_send_recv(&hm, &hr);
362
363 *pw_module_type = hr.u.a.adapter_type;
364 *pw_num_outputs = hr.u.a.num_outstreams;
365 *pw_num_inputs = hr.u.a.num_instreams;
366 *pw_version = hr.u.a.version;
367 *pserial_number = hr.u.a.serial_number;
368 *ph_module = 0;
369
370 return hr.error;
371}
372
373u16 hpi_adapter_get_assert(const struct hpi_hsubsys *ph_subsys,
374 u16 adapter_index, u16 *assert_present, char *psz_assert,
375 u16 *pw_line_number)
376{
377 struct hpi_message hm;
378 struct hpi_response hr;
379 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
380 HPI_ADAPTER_GET_ASSERT);
381 hm.adapter_index = adapter_index;
382 hpi_send_recv(&hm, &hr);
383
384 *assert_present = 0;
385
386 if (!hr.error) {
387
388 *pw_line_number = (u16)hr.u.a.serial_number;
389 if (*pw_line_number) {
390
391 int i;
392 char *src = (char *)hr.u.a.sz_adapter_assert;
393 char *dst = psz_assert;
394
395 *assert_present = 1;
396
397 for (i = 0; i < HPI_STRING_LEN; i++) {
398 char c;
399 c = *src++;
400 *dst++ = c;
401 if (c == 0)
402 break;
403 }
404
405 }
406 }
407 return hr.error;
408}
409
410u16 hpi_adapter_get_assert_ex(const struct hpi_hsubsys *ph_subsys,
411 u16 adapter_index, u16 *assert_present, char *psz_assert,
412 u32 *pline_number, u16 *pw_assert_on_dsp)
413{
414 struct hpi_message hm;
415 struct hpi_response hr;
416 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
417 HPI_ADAPTER_GET_ASSERT);
418 hm.adapter_index = adapter_index;
419
420 hpi_send_recv(&hm, &hr);
421
422 *assert_present = 0;
423
424 if (!hr.error) {
425
426 *pline_number = hr.u.a.serial_number;
427
428 *assert_present = hr.u.a.adapter_type;
429
430 *pw_assert_on_dsp = hr.u.a.adapter_index;
431
432 if (!*assert_present && *pline_number)
433
434 *assert_present = 1;
435
436 if (*assert_present) {
437
438 int i;
439 char *src = (char *)hr.u.a.sz_adapter_assert;
440 char *dst = psz_assert;
441
442 for (i = 0; i < HPI_STRING_LEN; i++) {
443 char c;
444 c = *src++;
445 *dst++ = c;
446 if (c == 0)
447 break;
448 }
449
450 } else {
451 *psz_assert = 0;
452 }
453 }
454 return hr.error;
455}
456
457u16 hpi_adapter_test_assert(const struct hpi_hsubsys *ph_subsys,
458 u16 adapter_index, u16 assert_id)
459{
460 struct hpi_message hm;
461 struct hpi_response hr;
462 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
463 HPI_ADAPTER_TEST_ASSERT);
464 hm.adapter_index = adapter_index;
465 hm.u.a.assert_id = assert_id;
466
467 hpi_send_recv(&hm, &hr);
468
469 return hr.error;
470}
471
472u16 hpi_adapter_enable_capability(const struct hpi_hsubsys *ph_subsys,
473 u16 adapter_index, u16 capability, u32 key)
474{
475 struct hpi_message hm;
476 struct hpi_response hr;
477 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
478 HPI_ADAPTER_ENABLE_CAPABILITY);
479 hm.adapter_index = adapter_index;
480 hm.u.a.assert_id = capability;
481 hm.u.a.adapter_mode = key;
482
483 hpi_send_recv(&hm, &hr);
484
485 return hr.error;
486}
487
488u16 hpi_adapter_self_test(const struct hpi_hsubsys *ph_subsys,
489 u16 adapter_index)
490{
491 struct hpi_message hm;
492 struct hpi_response hr;
493 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
494 HPI_ADAPTER_SELFTEST);
495 hm.adapter_index = adapter_index;
496 hpi_send_recv(&hm, &hr);
497 return hr.error;
498}
499
500u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
501 u16 adapter_index, u32 dsp_address, char *p_buffer, int *count_bytes)
502{
503 struct hpi_message hm;
504 struct hpi_response hr;
505 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
506 HPI_ADAPTER_DEBUG_READ);
507
508 hr.size = sizeof(hr);
509
510 hm.adapter_index = adapter_index;
511 hm.u.ax.debug_read.dsp_address = dsp_address;
512
513 if (*count_bytes > sizeof(hr.u.bytes))
514 *count_bytes = sizeof(hr.u.bytes);
515
516 hm.u.ax.debug_read.count_bytes = *count_bytes;
517
518 hpi_send_recv(&hm, &hr);
519
520 if (!hr.error) {
521 *count_bytes = hr.size - 12;
522 memcpy(p_buffer, &hr.u.bytes, *count_bytes);
523 } else
524 *count_bytes = 0;
525 return hr.error;
526}
527
528u16 hpi_adapter_set_property(const struct hpi_hsubsys *ph_subsys,
529 u16 adapter_index, u16 property, u16 parameter1, u16 parameter2)
530{
531 struct hpi_message hm;
532 struct hpi_response hr;
533 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
534 HPI_ADAPTER_SET_PROPERTY);
535 hm.adapter_index = adapter_index;
536 hm.u.ax.property_set.property = property;
537 hm.u.ax.property_set.parameter1 = parameter1;
538 hm.u.ax.property_set.parameter2 = parameter2;
539
540 hpi_send_recv(&hm, &hr);
541
542 return hr.error;
543}
544
545u16 hpi_adapter_get_property(const struct hpi_hsubsys *ph_subsys,
546 u16 adapter_index, u16 property, u16 *pw_parameter1,
547 u16 *pw_parameter2)
548{
549 struct hpi_message hm;
550 struct hpi_response hr;
551 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
552 HPI_ADAPTER_GET_PROPERTY);
553 hm.adapter_index = adapter_index;
554 hm.u.ax.property_set.property = property;
555
556 hpi_send_recv(&hm, &hr);
557 if (!hr.error) {
558 if (pw_parameter1)
559 *pw_parameter1 = hr.u.ax.property_get.parameter1;
560 if (pw_parameter2)
561 *pw_parameter2 = hr.u.ax.property_get.parameter2;
562 }
563
564 return hr.error;
565}
566
567u16 hpi_adapter_enumerate_property(const struct hpi_hsubsys *ph_subsys,
568 u16 adapter_index, u16 index, u16 what_to_enumerate,
569 u16 property_index, u32 *psetting)
570{
571 return 0;
572}
573
574u16 hpi_format_create(struct hpi_format *p_format, u16 channels, u16 format,
575 u32 sample_rate, u32 bit_rate, u32 attributes)
576{
577 u16 error = 0;
578 struct hpi_msg_format fmt;
579
580 switch (channels) {
581 case 1:
582 case 2:
583 case 4:
584 case 6:
585 case 8:
586 case 16:
587 break;
588 default:
589 error = HPI_ERROR_INVALID_CHANNELS;
590 return error;
591 }
592 fmt.channels = channels;
593
594 switch (format) {
595 case HPI_FORMAT_PCM16_SIGNED:
596 case HPI_FORMAT_PCM24_SIGNED:
597 case HPI_FORMAT_PCM32_SIGNED:
598 case HPI_FORMAT_PCM32_FLOAT:
599 case HPI_FORMAT_PCM16_BIGENDIAN:
600 case HPI_FORMAT_PCM8_UNSIGNED:
601 case HPI_FORMAT_MPEG_L1:
602 case HPI_FORMAT_MPEG_L2:
603 case HPI_FORMAT_MPEG_L3:
604 case HPI_FORMAT_DOLBY_AC2:
605 case HPI_FORMAT_AA_TAGIT1_HITS:
606 case HPI_FORMAT_AA_TAGIT1_INSERTS:
607 case HPI_FORMAT_RAW_BITSTREAM:
608 case HPI_FORMAT_AA_TAGIT1_HITS_EX1:
609 case HPI_FORMAT_OEM1:
610 case HPI_FORMAT_OEM2:
611 break;
612 default:
613 error = HPI_ERROR_INVALID_FORMAT;
614 return error;
615 }
616 fmt.format = format;
617
618 if (sample_rate < 8000L) {
619 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
620 sample_rate = 8000L;
621 }
622 if (sample_rate > 200000L) {
623 error = HPI_ERROR_INCOMPATIBLE_SAMPLERATE;
624 sample_rate = 200000L;
625 }
626 fmt.sample_rate = sample_rate;
627
628 switch (format) {
629 case HPI_FORMAT_MPEG_L1:
630 case HPI_FORMAT_MPEG_L2:
631 case HPI_FORMAT_MPEG_L3:
632 fmt.bit_rate = bit_rate;
633 break;
634 case HPI_FORMAT_PCM16_SIGNED:
635 case HPI_FORMAT_PCM16_BIGENDIAN:
636 fmt.bit_rate = channels * sample_rate * 2;
637 break;
638 case HPI_FORMAT_PCM32_SIGNED:
639 case HPI_FORMAT_PCM32_FLOAT:
640 fmt.bit_rate = channels * sample_rate * 4;
641 break;
642 case HPI_FORMAT_PCM8_UNSIGNED:
643 fmt.bit_rate = channels * sample_rate;
644 break;
645 default:
646 fmt.bit_rate = 0;
647 }
648
649 switch (format) {
650 case HPI_FORMAT_MPEG_L2:
651 if ((channels == 1)
652 && (attributes != HPI_MPEG_MODE_DEFAULT)) {
653 attributes = HPI_MPEG_MODE_DEFAULT;
654 error = HPI_ERROR_INVALID_FORMAT;
655 } else if (attributes > HPI_MPEG_MODE_DUALCHANNEL) {
656 attributes = HPI_MPEG_MODE_DEFAULT;
657 error = HPI_ERROR_INVALID_FORMAT;
658 }
659 fmt.attributes = attributes;
660 break;
661 default:
662 fmt.attributes = attributes;
663 }
664
665 hpi_msg_to_format(p_format, &fmt);
666 return error;
667}
668
669u16 hpi_stream_estimate_buffer_size(struct hpi_format *p_format,
670 u32 host_polling_rate_in_milli_seconds, u32 *recommended_buffer_size)
671{
672
673 u32 bytes_per_second;
674 u32 size;
675 u16 channels;
676 struct hpi_format *pF = p_format;
677
678 channels = pF->channels;
679
680 switch (pF->format) {
681 case HPI_FORMAT_PCM16_BIGENDIAN:
682 case HPI_FORMAT_PCM16_SIGNED:
683 bytes_per_second = pF->sample_rate * 2L * channels;
684 break;
685 case HPI_FORMAT_PCM24_SIGNED:
686 bytes_per_second = pF->sample_rate * 3L * channels;
687 break;
688 case HPI_FORMAT_PCM32_SIGNED:
689 case HPI_FORMAT_PCM32_FLOAT:
690 bytes_per_second = pF->sample_rate * 4L * channels;
691 break;
692 case HPI_FORMAT_PCM8_UNSIGNED:
693 bytes_per_second = pF->sample_rate * 1L * channels;
694 break;
695 case HPI_FORMAT_MPEG_L1:
696 case HPI_FORMAT_MPEG_L2:
697 case HPI_FORMAT_MPEG_L3:
698 bytes_per_second = pF->bit_rate / 8L;
699 break;
700 case HPI_FORMAT_DOLBY_AC2:
701
702 bytes_per_second = 256000L / 8L;
703 break;
704 default:
705 return HPI_ERROR_INVALID_FORMAT;
706 }
707 size = (bytes_per_second * host_polling_rate_in_milli_seconds * 2) /
708 1000L;
709
710 *recommended_buffer_size =
711 roundup_pow_of_two(((size + 4095L) & ~4095L));
712 return 0;
713}
714
715u16 hpi_outstream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
716 u16 outstream_index, u32 *ph_outstream)
717{
718 struct hpi_message hm;
719 struct hpi_response hr;
720 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
721 HPI_OSTREAM_OPEN);
722 hm.adapter_index = adapter_index;
723 hm.obj_index = outstream_index;
724
725 hpi_send_recv(&hm, &hr);
726
727 if (hr.error == 0)
728 *ph_outstream =
729 hpi_indexes_to_handle(HPI_OBJ_OSTREAM, adapter_index,
730 outstream_index);
731 else
732 *ph_outstream = 0;
733 return hr.error;
734}
735
736u16 hpi_outstream_close(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
737{
738 struct hpi_message hm;
739 struct hpi_response hr;
740
741 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
742 HPI_OSTREAM_HOSTBUFFER_FREE);
743 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
744 hpi_send_recv(&hm, &hr);
745
746 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
747 HPI_OSTREAM_GROUP_RESET);
748 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
749 hpi_send_recv(&hm, &hr);
750
751 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
752 HPI_OSTREAM_CLOSE);
753 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
754 hpi_send_recv(&hm, &hr);
755
756 return hr.error;
757}
758
759u16 hpi_outstream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
760 u32 h_outstream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_to_play,
761 u32 *psamples_played, u32 *pauxiliary_data_to_play)
762{
763 struct hpi_message hm;
764 struct hpi_response hr;
765 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
766 HPI_OSTREAM_GET_INFO);
767 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
768
769 hpi_send_recv(&hm, &hr);
770
771 if (pw_state)
772 *pw_state = hr.u.d.u.stream_info.state;
773 if (pbuffer_size)
774 *pbuffer_size = hr.u.d.u.stream_info.buffer_size;
775 if (pdata_to_play)
776 *pdata_to_play = hr.u.d.u.stream_info.data_available;
777 if (psamples_played)
778 *psamples_played = hr.u.d.u.stream_info.samples_transferred;
779 if (pauxiliary_data_to_play)
780 *pauxiliary_data_to_play =
781 hr.u.d.u.stream_info.auxiliary_data_available;
782 return hr.error;
783}
784
785u16 hpi_outstream_write_buf(const struct hpi_hsubsys *ph_subsys,
786 u32 h_outstream, const u8 *pb_data, u32 bytes_to_write,
787 const struct hpi_format *p_format)
788{
789 struct hpi_message hm;
790 struct hpi_response hr;
791 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
792 HPI_OSTREAM_WRITE);
793 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
794 hm.u.d.u.data.pb_data = (u8 *)pb_data;
795 hm.u.d.u.data.data_size = bytes_to_write;
796
797 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
798
799 hpi_send_recv(&hm, &hr);
800
801 return hr.error;
802}
803
804u16 hpi_outstream_start(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
805{
806 struct hpi_message hm;
807 struct hpi_response hr;
808 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
809 HPI_OSTREAM_START);
810 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
811
812 hpi_send_recv(&hm, &hr);
813
814 return hr.error;
815}
816
817u16 hpi_outstream_wait_start(const struct hpi_hsubsys *ph_subsys,
818 u32 h_outstream)
819{
820 struct hpi_message hm;
821 struct hpi_response hr;
822 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
823 HPI_OSTREAM_WAIT_START);
824 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
825
826 hpi_send_recv(&hm, &hr);
827
828 return hr.error;
829}
830
831u16 hpi_outstream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
832{
833 struct hpi_message hm;
834 struct hpi_response hr;
835 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
836 HPI_OSTREAM_STOP);
837 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
838
839 hpi_send_recv(&hm, &hr);
840
841 return hr.error;
842}
843
844u16 hpi_outstream_sinegen(const struct hpi_hsubsys *ph_subsys,
845 u32 h_outstream)
846{
847 struct hpi_message hm;
848 struct hpi_response hr;
849 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
850 HPI_OSTREAM_SINEGEN);
851 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
852
853 hpi_send_recv(&hm, &hr);
854
855 return hr.error;
856}
857
858u16 hpi_outstream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_outstream)
859{
860 struct hpi_message hm;
861 struct hpi_response hr;
862 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
863 HPI_OSTREAM_RESET);
864 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
865
866 hpi_send_recv(&hm, &hr);
867
868 return hr.error;
869}
870
871u16 hpi_outstream_query_format(const struct hpi_hsubsys *ph_subsys,
872 u32 h_outstream, struct hpi_format *p_format)
873{
874 struct hpi_message hm;
875 struct hpi_response hr;
876
877 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
878 HPI_OSTREAM_QUERY_FORMAT);
879 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
880
881 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
882
883 hpi_send_recv(&hm, &hr);
884
885 return hr.error;
886}
887
888u16 hpi_outstream_set_format(const struct hpi_hsubsys *ph_subsys,
889 u32 h_outstream, struct hpi_format *p_format)
890{
891 struct hpi_message hm;
892 struct hpi_response hr;
893
894 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
895 HPI_OSTREAM_SET_FORMAT);
896 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
897
898 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
899
900 hpi_send_recv(&hm, &hr);
901
902 return hr.error;
903}
904
905u16 hpi_outstream_set_velocity(const struct hpi_hsubsys *ph_subsys,
906 u32 h_outstream, short velocity)
907{
908 struct hpi_message hm;
909 struct hpi_response hr;
910
911 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
912 HPI_OSTREAM_SET_VELOCITY);
913 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
914 hm.u.d.u.velocity = velocity;
915
916 hpi_send_recv(&hm, &hr);
917
918 return hr.error;
919}
920
921u16 hpi_outstream_set_punch_in_out(const struct hpi_hsubsys *ph_subsys,
922 u32 h_outstream, u32 punch_in_sample, u32 punch_out_sample)
923{
924 struct hpi_message hm;
925 struct hpi_response hr;
926
927 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
928 HPI_OSTREAM_SET_PUNCHINOUT);
929 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
930
931 hm.u.d.u.pio.punch_in_sample = punch_in_sample;
932 hm.u.d.u.pio.punch_out_sample = punch_out_sample;
933
934 hpi_send_recv(&hm, &hr);
935
936 return hr.error;
937}
938
939u16 hpi_outstream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
940 u32 h_outstream, u16 mode)
941{
942 struct hpi_message hm;
943 struct hpi_response hr;
944
945 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
946 HPI_OSTREAM_ANC_RESET);
947 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
948 hm.u.d.u.data.format.channels = mode;
949 hpi_send_recv(&hm, &hr);
950 return hr.error;
951}
952
953u16 hpi_outstream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
954 u32 h_outstream, u32 *pframes_available)
955{
956 struct hpi_message hm;
957 struct hpi_response hr;
958
959 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
960 HPI_OSTREAM_ANC_GET_INFO);
961 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
962 hpi_send_recv(&hm, &hr);
963 if (hr.error == 0) {
964 if (pframes_available)
965 *pframes_available =
966 hr.u.d.u.stream_info.data_available /
967 sizeof(struct hpi_anc_frame);
968 }
969 return hr.error;
970}
971
972u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
973 u32 h_outstream, struct hpi_anc_frame *p_anc_frame_buffer,
974 u32 anc_frame_buffer_size_in_bytes,
975 u32 number_of_ancillary_frames_to_read)
976{
977 struct hpi_message hm;
978 struct hpi_response hr;
979 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
980 HPI_OSTREAM_ANC_READ);
981 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
982 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
983 hm.u.d.u.data.data_size =
984 number_of_ancillary_frames_to_read *
985 sizeof(struct hpi_anc_frame);
986 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
987 hpi_send_recv(&hm, &hr);
988 else
989 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER;
990 return hr.error;
991}
992
993u16 hpi_outstream_set_time_scale(const struct hpi_hsubsys *ph_subsys,
994 u32 h_outstream, u32 time_scale)
995{
996 struct hpi_message hm;
997 struct hpi_response hr;
998
999 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1000 HPI_OSTREAM_SET_TIMESCALE);
1001 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1002
1003 hm.u.d.u.time_scale = time_scale;
1004
1005 hpi_send_recv(&hm, &hr);
1006
1007 return hr.error;
1008}
1009
1010u16 hpi_outstream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1011 u32 h_outstream, u32 size_in_bytes)
1012{
1013 struct hpi_message hm;
1014 struct hpi_response hr;
1015
1016 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1017 HPI_OSTREAM_HOSTBUFFER_ALLOC);
1018 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1019 hm.u.d.u.data.data_size = size_in_bytes;
1020 hpi_send_recv(&hm, &hr);
1021 return hr.error;
1022}
1023
1024u16 hpi_outstream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1025 u32 h_outstream, u8 **pp_buffer,
1026 struct hpi_hostbuffer_status **pp_status)
1027{
1028 struct hpi_message hm;
1029 struct hpi_response hr;
1030
1031 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1032 HPI_OSTREAM_HOSTBUFFER_GET_INFO);
1033 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1034 hpi_send_recv(&hm, &hr);
1035
1036 if (hr.error == 0) {
1037 if (pp_buffer)
1038 *pp_buffer = hr.u.d.u.hostbuffer_info.p_buffer;
1039 if (pp_status)
1040 *pp_status = hr.u.d.u.hostbuffer_info.p_status;
1041 }
1042 return hr.error;
1043}
1044
1045u16 hpi_outstream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1046 u32 h_outstream)
1047{
1048 struct hpi_message hm;
1049 struct hpi_response hr;
1050
1051 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1052 HPI_OSTREAM_HOSTBUFFER_FREE);
1053 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1054 hpi_send_recv(&hm, &hr);
1055 return hr.error;
1056}
1057
1058u16 hpi_outstream_group_add(const struct hpi_hsubsys *ph_subsys,
1059 u32 h_outstream, u32 h_stream)
1060{
1061 struct hpi_message hm;
1062 struct hpi_response hr;
1063 u16 adapter;
1064 char c_obj_type;
1065
1066 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1067 HPI_OSTREAM_GROUP_ADD);
1068 hr.error = 0;
1069 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1070 c_obj_type = hpi_handle_object(h_stream);
1071 switch (c_obj_type) {
1072 case HPI_OBJ_OSTREAM:
1073 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1074 u32TOINDEXES(h_stream, &adapter,
1075 &hm.u.d.u.stream.stream_index);
1076 break;
1077 case HPI_OBJ_ISTREAM:
1078 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM;
1079 u32TOINDEXES(h_stream, &adapter,
1080 &hm.u.d.u.stream.stream_index);
1081 break;
1082 default:
1083 return HPI_ERROR_INVALID_STREAM;
1084 }
1085 if (adapter != hm.adapter_index)
1086 return HPI_ERROR_NO_INTERADAPTER_GROUPS;
1087
1088 hpi_send_recv(&hm, &hr);
1089 return hr.error;
1090}
1091
1092u16 hpi_outstream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1093 u32 h_outstream, u32 *poutstream_map, u32 *pinstream_map)
1094{
1095 struct hpi_message hm;
1096 struct hpi_response hr;
1097
1098 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1099 HPI_OSTREAM_GROUP_GETMAP);
1100 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1101 hpi_send_recv(&hm, &hr);
1102
1103 if (poutstream_map)
1104 *poutstream_map = hr.u.d.u.group_info.outstream_group_map;
1105 if (pinstream_map)
1106 *pinstream_map = hr.u.d.u.group_info.instream_group_map;
1107
1108 return hr.error;
1109}
1110
1111u16 hpi_outstream_group_reset(const struct hpi_hsubsys *ph_subsys,
1112 u32 h_outstream)
1113{
1114 struct hpi_message hm;
1115 struct hpi_response hr;
1116
1117 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
1118 HPI_OSTREAM_GROUP_RESET);
1119 u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
1120 hpi_send_recv(&hm, &hr);
1121 return hr.error;
1122}
1123
1124u16 hpi_instream_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1125 u16 instream_index, u32 *ph_instream)
1126{
1127 struct hpi_message hm;
1128 struct hpi_response hr;
1129
1130 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1131 HPI_ISTREAM_OPEN);
1132 hm.adapter_index = adapter_index;
1133 hm.obj_index = instream_index;
1134
1135 hpi_send_recv(&hm, &hr);
1136
1137 if (hr.error == 0)
1138 *ph_instream =
1139 hpi_indexes_to_handle(HPI_OBJ_ISTREAM, adapter_index,
1140 instream_index);
1141 else
1142 *ph_instream = 0;
1143
1144 return hr.error;
1145}
1146
1147u16 hpi_instream_close(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1148{
1149 struct hpi_message hm;
1150 struct hpi_response hr;
1151
1152 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1153 HPI_ISTREAM_HOSTBUFFER_FREE);
1154 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1155 hpi_send_recv(&hm, &hr);
1156
1157 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1158 HPI_ISTREAM_GROUP_RESET);
1159 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1160 hpi_send_recv(&hm, &hr);
1161
1162 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1163 HPI_ISTREAM_CLOSE);
1164 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1165 hpi_send_recv(&hm, &hr);
1166
1167 return hr.error;
1168}
1169
1170u16 hpi_instream_query_format(const struct hpi_hsubsys *ph_subsys,
1171 u32 h_instream, const struct hpi_format *p_format)
1172{
1173 struct hpi_message hm;
1174 struct hpi_response hr;
1175
1176 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1177 HPI_ISTREAM_QUERY_FORMAT);
1178 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1179 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1180
1181 hpi_send_recv(&hm, &hr);
1182
1183 return hr.error;
1184}
1185
1186u16 hpi_instream_set_format(const struct hpi_hsubsys *ph_subsys,
1187 u32 h_instream, const struct hpi_format *p_format)
1188{
1189 struct hpi_message hm;
1190 struct hpi_response hr;
1191
1192 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1193 HPI_ISTREAM_SET_FORMAT);
1194 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1195 hpi_format_to_msg(&hm.u.d.u.data.format, p_format);
1196
1197 hpi_send_recv(&hm, &hr);
1198
1199 return hr.error;
1200}
1201
1202u16 hpi_instream_read_buf(const struct hpi_hsubsys *ph_subsys, u32 h_instream,
1203 u8 *pb_data, u32 bytes_to_read)
1204{
1205 struct hpi_message hm;
1206 struct hpi_response hr;
1207
1208 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1209 HPI_ISTREAM_READ);
1210 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1211 hm.u.d.u.data.data_size = bytes_to_read;
1212 hm.u.d.u.data.pb_data = pb_data;
1213
1214 hpi_send_recv(&hm, &hr);
1215
1216 return hr.error;
1217}
1218
1219u16 hpi_instream_start(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1220{
1221 struct hpi_message hm;
1222 struct hpi_response hr;
1223
1224 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1225 HPI_ISTREAM_START);
1226 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1227
1228 hpi_send_recv(&hm, &hr);
1229
1230 return hr.error;
1231}
1232
1233u16 hpi_instream_wait_start(const struct hpi_hsubsys *ph_subsys,
1234 u32 h_instream)
1235{
1236 struct hpi_message hm;
1237 struct hpi_response hr;
1238
1239 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1240 HPI_ISTREAM_WAIT_START);
1241 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1242
1243 hpi_send_recv(&hm, &hr);
1244
1245 return hr.error;
1246}
1247
1248u16 hpi_instream_stop(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1249{
1250 struct hpi_message hm;
1251 struct hpi_response hr;
1252
1253 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1254 HPI_ISTREAM_STOP);
1255 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1256
1257 hpi_send_recv(&hm, &hr);
1258
1259 return hr.error;
1260}
1261
1262u16 hpi_instream_reset(const struct hpi_hsubsys *ph_subsys, u32 h_instream)
1263{
1264 struct hpi_message hm;
1265 struct hpi_response hr;
1266
1267 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1268 HPI_ISTREAM_RESET);
1269 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1270
1271 hpi_send_recv(&hm, &hr);
1272
1273 return hr.error;
1274}
1275
1276u16 hpi_instream_get_info_ex(const struct hpi_hsubsys *ph_subsys,
1277 u32 h_instream, u16 *pw_state, u32 *pbuffer_size, u32 *pdata_recorded,
1278 u32 *psamples_recorded, u32 *pauxiliary_data_recorded)
1279{
1280 struct hpi_message hm;
1281 struct hpi_response hr;
1282 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1283 HPI_ISTREAM_GET_INFO);
1284 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1285
1286 hpi_send_recv(&hm, &hr);
1287
1288 if (pw_state)
1289 *pw_state = hr.u.d.u.stream_info.state;
1290 if (pbuffer_size)
1291 *pbuffer_size = hr.u.d.u.stream_info.buffer_size;
1292 if (pdata_recorded)
1293 *pdata_recorded = hr.u.d.u.stream_info.data_available;
1294 if (psamples_recorded)
1295 *psamples_recorded = hr.u.d.u.stream_info.samples_transferred;
1296 if (pauxiliary_data_recorded)
1297 *pauxiliary_data_recorded =
1298 hr.u.d.u.stream_info.auxiliary_data_available;
1299 return hr.error;
1300}
1301
1302u16 hpi_instream_ancillary_reset(const struct hpi_hsubsys *ph_subsys,
1303 u32 h_instream, u16 bytes_per_frame, u16 mode, u16 alignment,
1304 u16 idle_bit)
1305{
1306 struct hpi_message hm;
1307 struct hpi_response hr;
1308 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1309 HPI_ISTREAM_ANC_RESET);
1310 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1311 hm.u.d.u.data.format.attributes = bytes_per_frame;
1312 hm.u.d.u.data.format.format = (mode << 8) | (alignment & 0xff);
1313 hm.u.d.u.data.format.channels = idle_bit;
1314 hpi_send_recv(&hm, &hr);
1315 return hr.error;
1316}
1317
1318u16 hpi_instream_ancillary_get_info(const struct hpi_hsubsys *ph_subsys,
1319 u32 h_instream, u32 *pframe_space)
1320{
1321 struct hpi_message hm;
1322 struct hpi_response hr;
1323 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1324 HPI_ISTREAM_ANC_GET_INFO);
1325 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1326 hpi_send_recv(&hm, &hr);
1327 if (pframe_space)
1328 *pframe_space =
1329 (hr.u.d.u.stream_info.buffer_size -
1330 hr.u.d.u.stream_info.data_available) /
1331 sizeof(struct hpi_anc_frame);
1332 return hr.error;
1333}
1334
1335u16 hpi_instream_ancillary_write(const struct hpi_hsubsys *ph_subsys,
1336 u32 h_instream, const struct hpi_anc_frame *p_anc_frame_buffer,
1337 u32 anc_frame_buffer_size_in_bytes,
1338 u32 number_of_ancillary_frames_to_write)
1339{
1340 struct hpi_message hm;
1341 struct hpi_response hr;
1342
1343 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1344 HPI_ISTREAM_ANC_WRITE);
1345 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1346 hm.u.d.u.data.pb_data = (u8 *)p_anc_frame_buffer;
1347 hm.u.d.u.data.data_size =
1348 number_of_ancillary_frames_to_write *
1349 sizeof(struct hpi_anc_frame);
1350 if (hm.u.d.u.data.data_size <= anc_frame_buffer_size_in_bytes)
1351 hpi_send_recv(&hm, &hr);
1352 else
1353 hr.error = HPI_ERROR_INVALID_DATA_TRANSFER;
1354 return hr.error;
1355}
1356
1357u16 hpi_instream_host_buffer_allocate(const struct hpi_hsubsys *ph_subsys,
1358 u32 h_instream, u32 size_in_bytes)
1359{
1360
1361 struct hpi_message hm;
1362 struct hpi_response hr;
1363
1364 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1365 HPI_ISTREAM_HOSTBUFFER_ALLOC);
1366 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1367 hm.u.d.u.data.data_size = size_in_bytes;
1368 hpi_send_recv(&hm, &hr);
1369 return hr.error;
1370}
1371
1372u16 hpi_instream_host_buffer_get_info(const struct hpi_hsubsys *ph_subsys,
1373 u32 h_instream, u8 **pp_buffer,
1374 struct hpi_hostbuffer_status **pp_status)
1375{
1376 struct hpi_message hm;
1377 struct hpi_response hr;
1378
1379 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1380 HPI_ISTREAM_HOSTBUFFER_GET_INFO);
1381 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1382 hpi_send_recv(&hm, &hr);
1383
1384 if (hr.error == 0) {
1385 if (pp_buffer)
1386 *pp_buffer = hr.u.d.u.hostbuffer_info.p_buffer;
1387 if (pp_status)
1388 *pp_status = hr.u.d.u.hostbuffer_info.p_status;
1389 }
1390 return hr.error;
1391}
1392
1393u16 hpi_instream_host_buffer_free(const struct hpi_hsubsys *ph_subsys,
1394 u32 h_instream)
1395{
1396
1397 struct hpi_message hm;
1398 struct hpi_response hr;
1399
1400 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1401 HPI_ISTREAM_HOSTBUFFER_FREE);
1402 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1403 hpi_send_recv(&hm, &hr);
1404 return hr.error;
1405}
1406
1407u16 hpi_instream_group_add(const struct hpi_hsubsys *ph_subsys,
1408 u32 h_instream, u32 h_stream)
1409{
1410 struct hpi_message hm;
1411 struct hpi_response hr;
1412 u16 adapter;
1413 char c_obj_type;
1414
1415 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1416 HPI_ISTREAM_GROUP_ADD);
1417 hr.error = 0;
1418 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1419 c_obj_type = hpi_handle_object(h_stream);
1420
1421 switch (c_obj_type) {
1422 case HPI_OBJ_OSTREAM:
1423 hm.u.d.u.stream.object_type = HPI_OBJ_OSTREAM;
1424 u32TOINDEXES(h_stream, &adapter,
1425 &hm.u.d.u.stream.stream_index);
1426 break;
1427 case HPI_OBJ_ISTREAM:
1428 hm.u.d.u.stream.object_type = HPI_OBJ_ISTREAM;
1429 u32TOINDEXES(h_stream, &adapter,
1430 &hm.u.d.u.stream.stream_index);
1431 break;
1432 default:
1433 return HPI_ERROR_INVALID_STREAM;
1434 }
1435
1436 if (adapter != hm.adapter_index)
1437 return HPI_ERROR_NO_INTERADAPTER_GROUPS;
1438
1439 hpi_send_recv(&hm, &hr);
1440 return hr.error;
1441}
1442
1443u16 hpi_instream_group_get_map(const struct hpi_hsubsys *ph_subsys,
1444 u32 h_instream, u32 *poutstream_map, u32 *pinstream_map)
1445{
1446 struct hpi_message hm;
1447 struct hpi_response hr;
1448
1449 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1450 HPI_ISTREAM_HOSTBUFFER_FREE);
1451 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1452 hpi_send_recv(&hm, &hr);
1453
1454 if (poutstream_map)
1455 *poutstream_map = hr.u.d.u.group_info.outstream_group_map;
1456 if (pinstream_map)
1457 *pinstream_map = hr.u.d.u.group_info.instream_group_map;
1458
1459 return hr.error;
1460}
1461
1462u16 hpi_instream_group_reset(const struct hpi_hsubsys *ph_subsys,
1463 u32 h_instream)
1464{
1465 struct hpi_message hm;
1466 struct hpi_response hr;
1467
1468 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
1469 HPI_ISTREAM_GROUP_RESET);
1470 u32TOINDEXES(h_instream, &hm.adapter_index, &hm.obj_index);
1471 hpi_send_recv(&hm, &hr);
1472 return hr.error;
1473}
1474
1475u16 hpi_mixer_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
1476 u32 *ph_mixer)
1477{
1478 struct hpi_message hm;
1479 struct hpi_response hr;
1480 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
1481 hm.adapter_index = adapter_index;
1482
1483 hpi_send_recv(&hm, &hr);
1484
1485 if (hr.error == 0)
1486 *ph_mixer =
1487 hpi_indexes_to_handle(HPI_OBJ_MIXER, adapter_index,
1488 0);
1489 else
1490 *ph_mixer = 0;
1491 return hr.error;
1492}
1493
1494u16 hpi_mixer_close(const struct hpi_hsubsys *ph_subsys, u32 h_mixer)
1495{
1496 struct hpi_message hm;
1497 struct hpi_response hr;
1498 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE);
1499 u32TOINDEX(h_mixer, &hm.adapter_index);
1500 hpi_send_recv(&hm, &hr);
1501 return hr.error;
1502}
1503
1504u16 hpi_mixer_get_control(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1505 u16 src_node_type, u16 src_node_type_index, u16 dst_node_type,
1506 u16 dst_node_type_index, u16 control_type, u32 *ph_control)
1507{
1508 struct hpi_message hm;
1509 struct hpi_response hr;
1510 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1511 HPI_MIXER_GET_CONTROL);
1512 u32TOINDEX(h_mixer, &hm.adapter_index);
1513 hm.u.m.node_type1 = src_node_type;
1514 hm.u.m.node_index1 = src_node_type_index;
1515 hm.u.m.node_type2 = dst_node_type;
1516 hm.u.m.node_index2 = dst_node_type_index;
1517 hm.u.m.control_type = control_type;
1518
1519 hpi_send_recv(&hm, &hr);
1520
1521 if (hr.error == 0)
1522 *ph_control =
1523 hpi_indexes_to_handle(HPI_OBJ_CONTROL,
1524 hm.adapter_index, hr.u.m.control_index);
1525 else
1526 *ph_control = 0;
1527 return hr.error;
1528}
1529
1530u16 hpi_mixer_get_control_by_index(const struct hpi_hsubsys *ph_subsys,
1531 u32 h_mixer, u16 control_index, u16 *pw_src_node_type,
1532 u16 *pw_src_node_index, u16 *pw_dst_node_type, u16 *pw_dst_node_index,
1533 u16 *pw_control_type, u32 *ph_control)
1534{
1535 struct hpi_message hm;
1536 struct hpi_response hr;
1537 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER,
1538 HPI_MIXER_GET_CONTROL_BY_INDEX);
1539 u32TOINDEX(h_mixer, &hm.adapter_index);
1540 hm.u.m.control_index = control_index;
1541 hpi_send_recv(&hm, &hr);
1542
1543 if (pw_src_node_type) {
1544 *pw_src_node_type =
1545 hr.u.m.src_node_type + HPI_SOURCENODE_NONE;
1546 *pw_src_node_index = hr.u.m.src_node_index;
1547 *pw_dst_node_type = hr.u.m.dst_node_type + HPI_DESTNODE_NONE;
1548 *pw_dst_node_index = hr.u.m.dst_node_index;
1549 }
1550 if (pw_control_type)
1551 *pw_control_type = hr.u.m.control_index;
1552
1553 if (ph_control) {
1554 if (hr.error == 0)
1555 *ph_control =
1556 hpi_indexes_to_handle(HPI_OBJ_CONTROL,
1557 hm.adapter_index, control_index);
1558 else
1559 *ph_control = 0;
1560 }
1561 return hr.error;
1562}
1563
1564u16 hpi_mixer_store(const struct hpi_hsubsys *ph_subsys, u32 h_mixer,
1565 enum HPI_MIXER_STORE_COMMAND command, u16 index)
1566{
1567 struct hpi_message hm;
1568 struct hpi_response hr;
1569 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_STORE);
1570 u32TOINDEX(h_mixer, &hm.adapter_index);
1571 hm.u.mx.store.command = command;
1572 hm.u.mx.store.index = index;
1573 hpi_send_recv(&hm, &hr);
1574 return hr.error;
1575}
1576
1577static
1578u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys,
1579 const u32 h_control, const u16 attrib, const u32 param1,
1580 const u32 param2)
1581{
1582 struct hpi_message hm;
1583 struct hpi_response hr;
1584 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1585 HPI_CONTROL_SET_STATE);
1586 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1587 hm.u.c.attribute = attrib;
1588 hm.u.c.param1 = param1;
1589 hm.u.c.param2 = param2;
1590 hpi_send_recv(&hm, &hr);
1591 return hr.error;
1592}
1593
1594static
1595u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
1596 const u32 h_control, const u16 attrib, u32 param1, u32 param2,
1597 u32 *pparam1, u32 *pparam2)
1598{
1599 struct hpi_message hm;
1600 struct hpi_response hr;
1601 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1602 HPI_CONTROL_GET_STATE);
1603 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1604 hm.u.c.attribute = attrib;
1605 hm.u.c.param1 = param1;
1606 hm.u.c.param2 = param2;
1607 hpi_send_recv(&hm, &hr);
1608 if (pparam1)
1609 *pparam1 = hr.u.c.param1;
1610 if (pparam2)
1611 *pparam2 = hr.u.c.param2;
1612
1613 return hr.error;
1614}
1615
1616#define hpi_control_param1_get(s, h, a, p1) \
1617 hpi_control_param_get(s, h, a, 0, 0, p1, NULL)
1618#define hpi_control_param2_get(s, h, a, p1, p2) \
1619 hpi_control_param_get(s, h, a, 0, 0, p1, p2)
1620#define hpi_control_ex_param1_get(s, h, a, p1) \
1621 hpi_control_ex_param_get(s, h, a, 0, 0, p1, NULL)
1622#define hpi_control_ex_param2_get(s, h, a, p1, p2) \
1623 hpi_control_ex_param_get(s, h, a, 0, 0, p1, p2)
1624
1625static
1626u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
1627 const u32 h_control, const u16 attrib, const u32 index,
1628 const u32 param, u32 *psetting)
1629{
1630 struct hpi_message hm;
1631 struct hpi_response hr;
1632 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1633 HPI_CONTROL_GET_INFO);
1634 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1635
1636 hm.u.c.attribute = attrib;
1637 hm.u.c.param1 = index;
1638 hm.u.c.param2 = param;
1639
1640 hpi_send_recv(&hm, &hr);
1641 *psetting = hr.u.c.param1;
1642
1643 return hr.error;
1644}
1645
1646static u16 hpi_control_get_string(const struct hpi_hsubsys *ph_subsys,
1647 const u32 h_control, const u16 attribute, char *psz_string,
1648 const u32 string_length)
1649{
1650 unsigned int sub_string_index = 0, j = 0;
1651 char c = 0;
1652 unsigned int n = 0;
1653 u16 hE = 0;
1654
1655 if ((string_length < 1) || (string_length > 256))
1656 return HPI_ERROR_INVALID_CONTROL_VALUE;
1657 for (sub_string_index = 0; sub_string_index < string_length;
1658 sub_string_index += 8) {
1659 struct hpi_message hm;
1660 struct hpi_response hr;
1661
1662 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1663 HPI_CONTROL_GET_STATE);
1664 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1665 hm.u.c.attribute = attribute;
1666 hm.u.c.param1 = sub_string_index;
1667 hm.u.c.param2 = 0;
1668 hpi_send_recv(&hm, &hr);
1669
1670 if (sub_string_index == 0
1671 && (hr.u.cu.chars8.remaining_chars + 8) >
1672 string_length)
1673 return HPI_ERROR_INVALID_CONTROL_VALUE;
1674
1675 if (hr.error) {
1676 hE = hr.error;
1677 break;
1678 }
1679 for (j = 0; j < 8; j++) {
1680 c = hr.u.cu.chars8.sz_data[j];
1681 psz_string[sub_string_index + j] = c;
1682 n++;
1683 if (n >= string_length) {
1684 psz_string[string_length - 1] = 0;
1685 hE = HPI_ERROR_INVALID_CONTROL_VALUE;
1686 break;
1687 }
1688 if (c == 0)
1689 break;
1690 }
1691
1692 if ((hr.u.cu.chars8.remaining_chars == 0)
1693 && ((sub_string_index + j) < string_length)
1694 && (c != 0)) {
1695 c = 0;
1696 psz_string[sub_string_index + j] = c;
1697 }
1698 if (c == 0)
1699 break;
1700 }
1701 return hE;
1702}
1703
1704u16 HPI_AESEBU__receiver_query_format(const struct hpi_hsubsys *ph_subsys,
1705 const u32 h_aes_rx, const u32 index, u16 *pw_format)
1706{
1707 u32 qr;
1708 u16 err;
1709
1710 err = hpi_control_query(ph_subsys, h_aes_rx, HPI_AESEBURX_FORMAT,
1711 index, 0, &qr);
1712 *pw_format = (u16)qr;
1713 return err;
1714}
1715
1716u16 HPI_AESEBU__receiver_set_format(const struct hpi_hsubsys *ph_subsys,
1717 u32 h_control, u16 format)
1718{
1719 return hpi_control_param_set(ph_subsys, h_control,
1720 HPI_AESEBURX_FORMAT, format, 0);
1721}
1722
1723u16 HPI_AESEBU__receiver_get_format(const struct hpi_hsubsys *ph_subsys,
1724 u32 h_control, u16 *pw_format)
1725{
1726 u16 err;
1727 u32 param;
1728
1729 err = hpi_control_param1_get(ph_subsys, h_control,
1730 HPI_AESEBURX_FORMAT, &param);
1731 if (!err && pw_format)
1732 *pw_format = (u16)param;
1733
1734 return err;
1735}
1736
1737u16 HPI_AESEBU__receiver_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
1738 u32 h_control, u32 *psample_rate)
1739{
1740 return hpi_control_param1_get(ph_subsys, h_control,
1741 HPI_AESEBURX_SAMPLERATE, psample_rate);
1742}
1743
1744u16 HPI_AESEBU__receiver_get_user_data(const struct hpi_hsubsys *ph_subsys,
1745 u32 h_control, u16 index, u16 *pw_data)
1746{
1747 struct hpi_message hm;
1748 struct hpi_response hr;
1749 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1750 HPI_CONTROL_GET_STATE);
1751 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1752 hm.u.c.attribute = HPI_AESEBURX_USERDATA;
1753 hm.u.c.param1 = index;
1754
1755 hpi_send_recv(&hm, &hr);
1756
1757 if (pw_data)
1758 *pw_data = (u16)hr.u.c.param2;
1759 return hr.error;
1760}
1761
1762u16 HPI_AESEBU__receiver_get_channel_status(const struct hpi_hsubsys
1763 *ph_subsys, u32 h_control, u16 index, u16 *pw_data)
1764{
1765 struct hpi_message hm;
1766 struct hpi_response hr;
1767 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1768 HPI_CONTROL_GET_STATE);
1769 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1770 hm.u.c.attribute = HPI_AESEBURX_CHANNELSTATUS;
1771 hm.u.c.param1 = index;
1772
1773 hpi_send_recv(&hm, &hr);
1774
1775 if (pw_data)
1776 *pw_data = (u16)hr.u.c.param2;
1777 return hr.error;
1778}
1779
1780u16 HPI_AESEBU__receiver_get_error_status(const struct hpi_hsubsys *ph_subsys,
1781 u32 h_control, u16 *pw_error_data)
1782{
1783 u32 error_data = 0;
1784 u16 error = 0;
1785
1786 error = hpi_control_param1_get(ph_subsys, h_control,
1787 HPI_AESEBURX_ERRORSTATUS, &error_data);
1788 if (pw_error_data)
1789 *pw_error_data = (u16)error_data;
1790 return error;
1791}
1792
1793u16 HPI_AESEBU__transmitter_set_sample_rate(const struct hpi_hsubsys
1794 *ph_subsys, u32 h_control, u32 sample_rate)
1795{
1796 return hpi_control_param_set(ph_subsys, h_control,
1797 HPI_AESEBUTX_SAMPLERATE, sample_rate, 0);
1798}
1799
1800u16 HPI_AESEBU__transmitter_set_user_data(const struct hpi_hsubsys *ph_subsys,
1801 u32 h_control, u16 index, u16 data)
1802{
1803 return hpi_control_param_set(ph_subsys, h_control,
1804 HPI_AESEBUTX_USERDATA, index, data);
1805}
1806
1807u16 HPI_AESEBU__transmitter_set_channel_status(const struct hpi_hsubsys
1808 *ph_subsys, u32 h_control, u16 index, u16 data)
1809{
1810 return hpi_control_param_set(ph_subsys, h_control,
1811 HPI_AESEBUTX_CHANNELSTATUS, index, data);
1812}
1813
1814u16 HPI_AESEBU__transmitter_get_channel_status(const struct hpi_hsubsys
1815 *ph_subsys, u32 h_control, u16 index, u16 *pw_data)
1816{
1817 return HPI_ERROR_INVALID_OPERATION;
1818}
1819
1820u16 HPI_AESEBU__transmitter_query_format(const struct hpi_hsubsys *ph_subsys,
1821 const u32 h_aes_tx, const u32 index, u16 *pw_format)
1822{
1823 u32 qr;
1824 u16 err;
1825
1826 err = hpi_control_query(ph_subsys, h_aes_tx, HPI_AESEBUTX_FORMAT,
1827 index, 0, &qr);
1828 *pw_format = (u16)qr;
1829 return err;
1830}
1831
1832u16 HPI_AESEBU__transmitter_set_format(const struct hpi_hsubsys *ph_subsys,
1833 u32 h_control, u16 output_format)
1834{
1835 return hpi_control_param_set(ph_subsys, h_control,
1836 HPI_AESEBUTX_FORMAT, output_format, 0);
1837}
1838
1839u16 HPI_AESEBU__transmitter_get_format(const struct hpi_hsubsys *ph_subsys,
1840 u32 h_control, u16 *pw_output_format)
1841{
1842 u16 err;
1843 u32 param;
1844
1845 err = hpi_control_param1_get(ph_subsys, h_control,
1846 HPI_AESEBUTX_FORMAT, &param);
1847 if (!err && pw_output_format)
1848 *pw_output_format = (u16)param;
1849
1850 return err;
1851}
1852
1853u16 hpi_bitstream_set_clock_edge(const struct hpi_hsubsys *ph_subsys,
1854 u32 h_control, u16 edge_type)
1855{
1856 return hpi_control_param_set(ph_subsys, h_control,
1857 HPI_BITSTREAM_CLOCK_EDGE, edge_type, 0);
1858}
1859
1860u16 hpi_bitstream_set_data_polarity(const struct hpi_hsubsys *ph_subsys,
1861 u32 h_control, u16 polarity)
1862{
1863 return hpi_control_param_set(ph_subsys, h_control,
1864 HPI_BITSTREAM_DATA_POLARITY, polarity, 0);
1865}
1866
1867u16 hpi_bitstream_get_activity(const struct hpi_hsubsys *ph_subsys,
1868 u32 h_control, u16 *pw_clk_activity, u16 *pw_data_activity)
1869{
1870 struct hpi_message hm;
1871 struct hpi_response hr;
1872 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
1873 HPI_CONTROL_GET_STATE);
1874 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1875 hm.u.c.attribute = HPI_BITSTREAM_ACTIVITY;
1876 hpi_send_recv(&hm, &hr);
1877 if (pw_clk_activity)
1878 *pw_clk_activity = (u16)hr.u.c.param1;
1879 if (pw_data_activity)
1880 *pw_data_activity = (u16)hr.u.c.param2;
1881 return hr.error;
1882}
1883
1884u16 hpi_channel_mode_query_mode(const struct hpi_hsubsys *ph_subsys,
1885 const u32 h_mode, const u32 index, u16 *pw_mode)
1886{
1887 u32 qr;
1888 u16 err;
1889
1890 err = hpi_control_query(ph_subsys, h_mode, HPI_CHANNEL_MODE_MODE,
1891 index, 0, &qr);
1892 *pw_mode = (u16)qr;
1893 return err;
1894}
1895
1896u16 hpi_channel_mode_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1897 u16 mode)
1898{
1899 return hpi_control_param_set(ph_subsys, h_control,
1900 HPI_CHANNEL_MODE_MODE, mode, 0);
1901}
1902
1903u16 hpi_channel_mode_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1904 u16 *mode)
1905{
1906 u32 mode32 = 0;
1907 u16 error = hpi_control_param1_get(ph_subsys, h_control,
1908 HPI_CHANNEL_MODE_MODE, &mode32);
1909 if (mode)
1910 *mode = (u16)mode32;
1911 return error;
1912}
1913
1914u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1915 u32 hmi_address, u32 byte_count, u8 *pb_data)
1916{
1917 struct hpi_message hm;
1918 struct hpi_response hr;
1919 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1920 HPI_CONTROL_SET_STATE);
1921 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1922
1923 hm.u.cx.u.cobranet_data.byte_count = byte_count;
1924 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
1925
1926 if (byte_count <= 8) {
1927 memcpy(hm.u.cx.u.cobranet_data.data, pb_data, byte_count);
1928 hm.u.cx.attribute = HPI_COBRANET_SET;
1929 } else {
1930 hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
1931 hm.u.cx.attribute = HPI_COBRANET_SET_DATA;
1932 }
1933
1934 hpi_send_recv(&hm, &hr);
1935
1936 return hr.error;
1937}
1938
1939u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
1940 u32 hmi_address, u32 max_byte_count, u32 *pbyte_count, u8 *pb_data)
1941{
1942 struct hpi_message hm;
1943 struct hpi_response hr;
1944 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1945 HPI_CONTROL_GET_STATE);
1946 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1947
1948 hm.u.cx.u.cobranet_data.byte_count = max_byte_count;
1949 hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
1950
1951 if (max_byte_count <= 8) {
1952 hm.u.cx.attribute = HPI_COBRANET_GET;
1953 } else {
1954 hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
1955 hm.u.cx.attribute = HPI_COBRANET_GET_DATA;
1956 }
1957
1958 hpi_send_recv(&hm, &hr);
1959 if (!hr.error && pb_data) {
1960
1961 *pbyte_count = hr.u.cx.u.cobranet_data.byte_count;
1962
1963 if (*pbyte_count < max_byte_count)
1964 max_byte_count = *pbyte_count;
1965
1966 if (hm.u.cx.attribute == HPI_COBRANET_GET) {
1967 memcpy(pb_data, hr.u.cx.u.cobranet_data.data,
1968 max_byte_count);
1969 } else {
1970
1971 }
1972
1973 }
1974 return hr.error;
1975}
1976
1977u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
1978 u32 h_control, u32 *pstatus, u32 *preadable_size,
1979 u32 *pwriteable_size)
1980{
1981 struct hpi_message hm;
1982 struct hpi_response hr;
1983 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
1984 HPI_CONTROL_GET_STATE);
1985 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
1986
1987 hm.u.cx.attribute = HPI_COBRANET_GET_STATUS;
1988
1989 hpi_send_recv(&hm, &hr);
1990 if (!hr.error) {
1991 if (pstatus)
1992 *pstatus = hr.u.cx.u.cobranet_status.status;
1993 if (preadable_size)
1994 *preadable_size =
1995 hr.u.cx.u.cobranet_status.readable_size;
1996 if (pwriteable_size)
1997 *pwriteable_size =
1998 hr.u.cx.u.cobranet_status.writeable_size;
1999 }
2000 return hr.error;
2001}
2002
2003u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
2004 u32 h_control, u32 *pi_paddress)
2005{
2006 u32 byte_count;
2007 u32 iP;
2008 u16 error;
2009 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2010 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count,
2011 (u8 *)&iP);
2012
2013 *pi_paddress =
2014 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2015 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2016
2017 if (error)
2018 *pi_paddress = 0;
2019
2020 return error;
2021
2022}
2023
2024u16 hpi_cobranet_setI_paddress(const struct hpi_hsubsys *ph_subsys,
2025 u32 h_control, u32 i_paddress)
2026{
2027 u32 iP;
2028 u16 error;
2029
2030 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) <<
2031 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress &
2032 0x000000ff) << 8);
2033
2034 error = hpi_cobranet_hmi_write(ph_subsys, h_control,
2035 HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, (u8 *)&iP);
2036
2037 return error;
2038
2039}
2040
2041u16 hpi_cobranet_get_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
2042 u32 h_control, u32 *pi_paddress)
2043{
2044 u32 byte_count;
2045 u32 iP;
2046 u16 error;
2047 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2048 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, &byte_count,
2049 (u8 *)&iP);
2050
2051 *pi_paddress =
2052 ((iP & 0xff000000) >> 8) | ((iP & 0x00ff0000) << 8) | ((iP &
2053 0x0000ff00) >> 8) | ((iP & 0x000000ff) << 8);
2054
2055 if (error)
2056 *pi_paddress = 0;
2057
2058 return error;
2059
2060}
2061
2062u16 hpi_cobranet_set_staticI_paddress(const struct hpi_hsubsys *ph_subsys,
2063 u32 h_control, u32 i_paddress)
2064{
2065 u32 iP;
2066 u16 error;
2067
2068 iP = ((i_paddress & 0xff000000) >> 8) | ((i_paddress & 0x00ff0000) <<
2069 8) | ((i_paddress & 0x0000ff00) >> 8) | ((i_paddress &
2070 0x000000ff) << 8);
2071
2072 error = hpi_cobranet_hmi_write(ph_subsys, h_control,
2073 HPI_COBRANET_HMI_cobra_ip_mon_staticIP, 4, (u8 *)&iP);
2074
2075 return error;
2076
2077}
2078
2079u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
2080 u32 h_control, u32 *pmAC_MS_bs, u32 *pmAC_LS_bs)
2081{
2082 u32 byte_count;
2083 u16 error;
2084 u32 mAC;
2085 error = hpi_cobranet_hmi_read(ph_subsys, h_control,
2086 HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count,
2087 (u8 *)&mAC);
2088 *pmAC_MS_bs =
2089 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC
2090 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8);
2091 error += hpi_cobranet_hmi_read(ph_subsys, h_control,
2092 HPI_COBRANET_HMI_cobra_if_phy_address + 1, 4, &byte_count,
2093 (u8 *)&mAC);
2094 *pmAC_LS_bs =
2095 ((mAC & 0xff000000) >> 8) | ((mAC & 0x00ff0000) << 8) | ((mAC
2096 & 0x0000ff00) >> 8) | ((mAC & 0x000000ff) << 8);
2097
2098 if (error) {
2099 *pmAC_MS_bs = 0;
2100 *pmAC_LS_bs = 0;
2101 }
2102
2103 return error;
2104}
2105
2106u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2107 u16 attack, u16 decay, short ratio100, short threshold0_01dB,
2108 short makeup_gain0_01dB)
2109{
2110 struct hpi_message hm;
2111 struct hpi_response hr;
2112 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2113 HPI_CONTROL_SET_STATE);
2114 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2115
2116 hm.u.c.param1 = attack + ((u32)ratio100 << 16);
2117 hm.u.c.param2 = (decay & 0xFFFFL);
2118 hm.u.c.an_log_value[0] = threshold0_01dB;
2119 hm.u.c.an_log_value[1] = makeup_gain0_01dB;
2120 hm.u.c.attribute = HPI_COMPANDER_PARAMS;
2121
2122 hpi_send_recv(&hm, &hr);
2123
2124 return hr.error;
2125}
2126
2127u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2128 u16 *pw_attack, u16 *pw_decay, short *pw_ratio100,
2129 short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB)
2130{
2131 struct hpi_message hm;
2132 struct hpi_response hr;
2133 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2134 HPI_CONTROL_GET_STATE);
2135 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2136 hm.u.c.attribute = HPI_COMPANDER_PARAMS;
2137
2138 hpi_send_recv(&hm, &hr);
2139
2140 if (pw_attack)
2141 *pw_attack = (short)(hr.u.c.param1 & 0xFFFF);
2142 if (pw_decay)
2143 *pw_decay = (short)(hr.u.c.param2 & 0xFFFF);
2144 if (pw_ratio100)
2145 *pw_ratio100 = (short)(hr.u.c.param1 >> 16);
2146
2147 if (pn_threshold0_01dB)
2148 *pn_threshold0_01dB = hr.u.c.an_log_value[0];
2149 if (pn_makeup_gain0_01dB)
2150 *pn_makeup_gain0_01dB = hr.u.c.an_log_value[1];
2151
2152 return hr.error;
2153}
2154
2155u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2156 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB)
2157{
2158 struct hpi_message hm;
2159 struct hpi_response hr;
2160 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2161 HPI_CONTROL_GET_STATE);
2162 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2163 hm.u.c.attribute = HPI_LEVEL_RANGE;
2164
2165 hpi_send_recv(&hm, &hr);
2166 if (hr.error) {
2167 hr.u.c.an_log_value[0] = 0;
2168 hr.u.c.an_log_value[1] = 0;
2169 hr.u.c.param1 = 0;
2170 }
2171 if (min_gain_01dB)
2172 *min_gain_01dB = hr.u.c.an_log_value[0];
2173 if (max_gain_01dB)
2174 *max_gain_01dB = hr.u.c.an_log_value[1];
2175 if (step_gain_01dB)
2176 *step_gain_01dB = (short)hr.u.c.param1;
2177 return hr.error;
2178}
2179
2180u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2181 short an_gain0_01dB[HPI_MAX_CHANNELS]
2182 )
2183{
2184 struct hpi_message hm;
2185 struct hpi_response hr;
2186
2187 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2188 HPI_CONTROL_SET_STATE);
2189 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2190 memcpy(hm.u.c.an_log_value, an_gain0_01dB,
2191 sizeof(short) * HPI_MAX_CHANNELS);
2192 hm.u.c.attribute = HPI_LEVEL_GAIN;
2193
2194 hpi_send_recv(&hm, &hr);
2195
2196 return hr.error;
2197}
2198
2199u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2200 short an_gain0_01dB[HPI_MAX_CHANNELS]
2201 )
2202{
2203 struct hpi_message hm;
2204 struct hpi_response hr;
2205 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2206 HPI_CONTROL_GET_STATE);
2207 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2208 hm.u.c.attribute = HPI_LEVEL_GAIN;
2209
2210 hpi_send_recv(&hm, &hr);
2211
2212 memcpy(an_gain0_01dB, hr.u.c.an_log_value,
2213 sizeof(short) * HPI_MAX_CHANNELS);
2214 return hr.error;
2215}
2216
2217u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys,
2218 const u32 h_meter, u32 *p_channels)
2219{
2220 return hpi_control_query(ph_subsys, h_meter, HPI_METER_NUM_CHANNELS,
2221 0, 0, p_channels);
2222}
2223
2224u16 hpi_meter_get_peak(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2225 short an_peakdB[HPI_MAX_CHANNELS]
2226 )
2227{
2228 short i = 0;
2229
2230 struct hpi_message hm;
2231 struct hpi_response hr;
2232
2233 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2234 HPI_CONTROL_GET_STATE);
2235 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2236 hm.obj_index = hm.obj_index;
2237 hm.u.c.attribute = HPI_METER_PEAK;
2238
2239 hpi_send_recv(&hm, &hr);
2240
2241 if (!hr.error)
2242 memcpy(an_peakdB, hr.u.c.an_log_value,
2243 sizeof(short) * HPI_MAX_CHANNELS);
2244 else
2245 for (i = 0; i < HPI_MAX_CHANNELS; i++)
2246 an_peakdB[i] = HPI_METER_MINIMUM;
2247 return hr.error;
2248}
2249
2250u16 hpi_meter_get_rms(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2251 short an_rmsdB[HPI_MAX_CHANNELS]
2252 )
2253{
2254 short i = 0;
2255
2256 struct hpi_message hm;
2257 struct hpi_response hr;
2258
2259 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2260 HPI_CONTROL_GET_STATE);
2261 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2262 hm.u.c.attribute = HPI_METER_RMS;
2263
2264 hpi_send_recv(&hm, &hr);
2265
2266 if (!hr.error)
2267 memcpy(an_rmsdB, hr.u.c.an_log_value,
2268 sizeof(short) * HPI_MAX_CHANNELS);
2269 else
2270 for (i = 0; i < HPI_MAX_CHANNELS; i++)
2271 an_rmsdB[i] = HPI_METER_MINIMUM;
2272
2273 return hr.error;
2274}
2275
2276u16 hpi_meter_set_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
2277 u32 h_control, u16 attack, u16 decay)
2278{
2279 return hpi_control_param_set(ph_subsys, h_control,
2280 HPI_METER_RMS_BALLISTICS, attack, decay);
2281}
2282
2283u16 hpi_meter_get_rms_ballistics(const struct hpi_hsubsys *ph_subsys,
2284 u32 h_control, u16 *pn_attack, u16 *pn_decay)
2285{
2286 u32 attack;
2287 u32 decay;
2288 u16 error;
2289
2290 error = hpi_control_param2_get(ph_subsys, h_control,
2291 HPI_METER_RMS_BALLISTICS, &attack, &decay);
2292
2293 if (pn_attack)
2294 *pn_attack = (unsigned short)attack;
2295 if (pn_decay)
2296 *pn_decay = (unsigned short)decay;
2297
2298 return error;
2299}
2300
2301u16 hpi_meter_set_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
2302 u32 h_control, u16 attack, u16 decay)
2303{
2304 return hpi_control_param_set(ph_subsys, h_control,
2305 HPI_METER_PEAK_BALLISTICS, attack, decay);
2306}
2307
2308u16 hpi_meter_get_peak_ballistics(const struct hpi_hsubsys *ph_subsys,
2309 u32 h_control, u16 *pn_attack, u16 *pn_decay)
2310{
2311 u32 attack;
2312 u32 decay;
2313 u16 error;
2314
2315 error = hpi_control_param2_get(ph_subsys, h_control,
2316 HPI_METER_PEAK_BALLISTICS, &attack, &decay);
2317
2318 if (pn_attack)
2319 *pn_attack = (short)attack;
2320 if (pn_decay)
2321 *pn_decay = (short)decay;
2322
2323 return error;
2324}
2325
2326u16 hpi_microphone_set_phantom_power(const struct hpi_hsubsys *ph_subsys,
2327 u32 h_control, u16 on_off)
2328{
2329 return hpi_control_param_set(ph_subsys, h_control,
2330 HPI_MICROPHONE_PHANTOM_POWER, (u32)on_off, 0);
2331}
2332
2333u16 hpi_microphone_get_phantom_power(const struct hpi_hsubsys *ph_subsys,
2334 u32 h_control, u16 *pw_on_off)
2335{
2336 u16 error = 0;
2337 u32 on_off = 0;
2338 error = hpi_control_param1_get(ph_subsys, h_control,
2339 HPI_MICROPHONE_PHANTOM_POWER, &on_off);
2340 if (pw_on_off)
2341 *pw_on_off = (u16)on_off;
2342 return error;
2343}
2344
2345u16 hpi_multiplexer_set_source(const struct hpi_hsubsys *ph_subsys,
2346 u32 h_control, u16 source_node_type, u16 source_node_index)
2347{
2348 return hpi_control_param_set(ph_subsys, h_control,
2349 HPI_MULTIPLEXER_SOURCE, source_node_type, source_node_index);
2350}
2351
2352u16 hpi_multiplexer_get_source(const struct hpi_hsubsys *ph_subsys,
2353 u32 h_control, u16 *source_node_type, u16 *source_node_index)
2354{
2355 u32 node, index;
2356 u16 error = hpi_control_param2_get(ph_subsys, h_control,
2357 HPI_MULTIPLEXER_SOURCE, &node,
2358 &index);
2359 if (source_node_type)
2360 *source_node_type = (u16)node;
2361 if (source_node_index)
2362 *source_node_index = (u16)index;
2363 return error;
2364}
2365
2366u16 hpi_multiplexer_query_source(const struct hpi_hsubsys *ph_subsys,
2367 u32 h_control, u16 index, u16 *source_node_type,
2368 u16 *source_node_index)
2369{
2370 struct hpi_message hm;
2371 struct hpi_response hr;
2372 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2373 HPI_CONTROL_GET_STATE);
2374 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2375 hm.u.c.attribute = HPI_MULTIPLEXER_QUERYSOURCE;
2376 hm.u.c.param1 = index;
2377
2378 hpi_send_recv(&hm, &hr);
2379
2380 if (source_node_type)
2381 *source_node_type = (u16)hr.u.c.param1;
2382 if (source_node_index)
2383 *source_node_index = (u16)hr.u.c.param2;
2384 return hr.error;
2385}
2386
2387u16 hpi_parametricEQ__get_info(const struct hpi_hsubsys *ph_subsys,
2388 u32 h_control, u16 *pw_number_of_bands, u16 *pw_on_off)
2389{
2390 u32 oB = 0;
2391 u32 oO = 0;
2392 u16 error = 0;
2393
2394 error = hpi_control_param2_get(ph_subsys, h_control,
2395 HPI_EQUALIZER_NUM_FILTERS, &oO, &oB);
2396 if (pw_number_of_bands)
2397 *pw_number_of_bands = (u16)oB;
2398 if (pw_on_off)
2399 *pw_on_off = (u16)oO;
2400 return error;
2401}
2402
2403u16 hpi_parametricEQ__set_state(const struct hpi_hsubsys *ph_subsys,
2404 u32 h_control, u16 on_off)
2405{
2406 return hpi_control_param_set(ph_subsys, h_control,
2407 HPI_EQUALIZER_NUM_FILTERS, on_off, 0);
2408}
2409
2410u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
2411 u32 h_control, u16 index, u16 *pn_type, u32 *pfrequency_hz,
2412 short *pnQ100, short *pn_gain0_01dB)
2413{
2414 struct hpi_message hm;
2415 struct hpi_response hr;
2416 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2417 HPI_CONTROL_GET_STATE);
2418 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2419 hm.u.c.attribute = HPI_EQUALIZER_FILTER;
2420 hm.u.c.param2 = index;
2421
2422 hpi_send_recv(&hm, &hr);
2423
2424 if (pfrequency_hz)
2425 *pfrequency_hz = hr.u.c.param1;
2426 if (pn_type)
2427 *pn_type = (u16)(hr.u.c.param2 >> 16);
2428 if (pnQ100)
2429 *pnQ100 = hr.u.c.an_log_value[1];
2430 if (pn_gain0_01dB)
2431 *pn_gain0_01dB = hr.u.c.an_log_value[0];
2432
2433 return hr.error;
2434}
2435
2436u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
2437 u32 h_control, u16 index, u16 type, u32 frequency_hz, short q100,
2438 short gain0_01dB)
2439{
2440 struct hpi_message hm;
2441 struct hpi_response hr;
2442 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2443 HPI_CONTROL_SET_STATE);
2444 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2445
2446 hm.u.c.param1 = frequency_hz;
2447 hm.u.c.param2 = (index & 0xFFFFL) + ((u32)type << 16);
2448 hm.u.c.an_log_value[0] = gain0_01dB;
2449 hm.u.c.an_log_value[1] = q100;
2450 hm.u.c.attribute = HPI_EQUALIZER_FILTER;
2451
2452 hpi_send_recv(&hm, &hr);
2453
2454 return hr.error;
2455}
2456
2457u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
2458 u32 h_control, u16 index, short coeffs[5]
2459 )
2460{
2461 struct hpi_message hm;
2462 struct hpi_response hr;
2463 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2464 HPI_CONTROL_GET_STATE);
2465 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2466 hm.u.c.attribute = HPI_EQUALIZER_COEFFICIENTS;
2467 hm.u.c.param2 = index;
2468
2469 hpi_send_recv(&hm, &hr);
2470
2471 coeffs[0] = (short)hr.u.c.an_log_value[0];
2472 coeffs[1] = (short)hr.u.c.an_log_value[1];
2473 coeffs[2] = (short)hr.u.c.param1;
2474 coeffs[3] = (short)(hr.u.c.param1 >> 16);
2475 coeffs[4] = (short)hr.u.c.param2;
2476
2477 return hr.error;
2478}
2479
2480u16 hpi_sample_clock_query_source(const struct hpi_hsubsys *ph_subsys,
2481 const u32 h_clock, const u32 index, u16 *pw_source)
2482{
2483 u32 qr;
2484 u16 err;
2485
2486 err = hpi_control_query(ph_subsys, h_clock, HPI_SAMPLECLOCK_SOURCE,
2487 index, 0, &qr);
2488 *pw_source = (u16)qr;
2489 return err;
2490}
2491
2492u16 hpi_sample_clock_set_source(const struct hpi_hsubsys *ph_subsys,
2493 u32 h_control, u16 source)
2494{
2495 return hpi_control_param_set(ph_subsys, h_control,
2496 HPI_SAMPLECLOCK_SOURCE, source, 0);
2497}
2498
2499u16 hpi_sample_clock_get_source(const struct hpi_hsubsys *ph_subsys,
2500 u32 h_control, u16 *pw_source)
2501{
2502 u16 error = 0;
2503 u32 source = 0;
2504 error = hpi_control_param1_get(ph_subsys, h_control,
2505 HPI_SAMPLECLOCK_SOURCE, &source);
2506 if (!error)
2507 if (pw_source)
2508 *pw_source = (u16)source;
2509 return error;
2510}
2511
2512u16 hpi_sample_clock_query_source_index(const struct hpi_hsubsys *ph_subsys,
2513 const u32 h_clock, const u32 index, const u32 source,
2514 u16 *pw_source_index)
2515{
2516 u32 qr;
2517 u16 err;
2518
2519 err = hpi_control_query(ph_subsys, h_clock,
2520 HPI_SAMPLECLOCK_SOURCE_INDEX, index, source, &qr);
2521 *pw_source_index = (u16)qr;
2522 return err;
2523}
2524
2525u16 hpi_sample_clock_set_source_index(const struct hpi_hsubsys *ph_subsys,
2526 u32 h_control, u16 source_index)
2527{
2528 return hpi_control_param_set(ph_subsys, h_control,
2529 HPI_SAMPLECLOCK_SOURCE_INDEX, source_index, 0);
2530}
2531
2532u16 hpi_sample_clock_get_source_index(const struct hpi_hsubsys *ph_subsys,
2533 u32 h_control, u16 *pw_source_index)
2534{
2535 u16 error = 0;
2536 u32 source_index = 0;
2537 error = hpi_control_param1_get(ph_subsys, h_control,
2538 HPI_SAMPLECLOCK_SOURCE_INDEX, &source_index);
2539 if (!error)
2540 if (pw_source_index)
2541 *pw_source_index = (u16)source_index;
2542 return error;
2543}
2544
2545u16 hpi_sample_clock_query_local_rate(const struct hpi_hsubsys *ph_subsys,
2546 const u32 h_clock, const u32 index, u32 *prate)
2547{
2548 u16 err;
2549 err = hpi_control_query(ph_subsys, h_clock,
2550 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, index, 0, prate);
2551
2552 return err;
2553}
2554
2555u16 hpi_sample_clock_set_local_rate(const struct hpi_hsubsys *ph_subsys,
2556 u32 h_control, u32 sample_rate)
2557{
2558 return hpi_control_param_set(ph_subsys, h_control,
2559 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, sample_rate, 0);
2560}
2561
2562u16 hpi_sample_clock_get_local_rate(const struct hpi_hsubsys *ph_subsys,
2563 u32 h_control, u32 *psample_rate)
2564{
2565 u16 error = 0;
2566 u32 sample_rate = 0;
2567 error = hpi_control_param1_get(ph_subsys, h_control,
2568 HPI_SAMPLECLOCK_LOCAL_SAMPLERATE, &sample_rate);
2569 if (!error)
2570 if (psample_rate)
2571 *psample_rate = sample_rate;
2572 return error;
2573}
2574
2575u16 hpi_sample_clock_get_sample_rate(const struct hpi_hsubsys *ph_subsys,
2576 u32 h_control, u32 *psample_rate)
2577{
2578 u16 error = 0;
2579 u32 sample_rate = 0;
2580 error = hpi_control_param1_get(ph_subsys, h_control,
2581 HPI_SAMPLECLOCK_SAMPLERATE, &sample_rate);
2582 if (!error)
2583 if (psample_rate)
2584 *psample_rate = sample_rate;
2585 return error;
2586}
2587
2588u16 hpi_sample_clock_set_auto(const struct hpi_hsubsys *ph_subsys,
2589 u32 h_control, u32 enable)
2590{
2591 return hpi_control_param_set(ph_subsys, h_control,
2592 HPI_SAMPLECLOCK_AUTO, enable, 0);
2593}
2594
2595u16 hpi_sample_clock_get_auto(const struct hpi_hsubsys *ph_subsys,
2596 u32 h_control, u32 *penable)
2597{
2598 return hpi_control_param1_get(ph_subsys, h_control,
2599 HPI_SAMPLECLOCK_AUTO, penable);
2600}
2601
2602u16 hpi_sample_clock_set_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
2603 u32 h_control, u32 lock)
2604{
2605 return hpi_control_param_set(ph_subsys, h_control,
2606 HPI_SAMPLECLOCK_LOCAL_LOCK, lock, 0);
2607}
2608
2609u16 hpi_sample_clock_get_local_rate_lock(const struct hpi_hsubsys *ph_subsys,
2610 u32 h_control, u32 *plock)
2611{
2612 return hpi_control_param1_get(ph_subsys, h_control,
2613 HPI_SAMPLECLOCK_LOCAL_LOCK, plock);
2614}
2615
2616u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys,
2617 u32 h_control, u32 index, u32 *frequency)
2618{
2619 return hpi_control_param_get(ph_subsys, h_control,
2620 HPI_TONEDETECTOR_FREQUENCY, index, 0, frequency, NULL);
2621}
2622
2623u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys,
2624 u32 h_control, u32 *state)
2625{
2626 return hpi_control_param_get(ph_subsys, h_control,
2627 HPI_TONEDETECTOR_STATE, 0, 0, (u32 *)state, NULL);
2628}
2629
2630u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
2631 u32 h_control, u32 enable)
2632{
2633 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2634 (u32)enable, 0);
2635}
2636
2637u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
2638 u32 h_control, u32 *enable)
2639{
2640 return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2641 0, 0, (u32 *)enable, NULL);
2642}
2643
2644u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
2645 u32 h_control, u32 event_enable)
2646{
2647 return hpi_control_param_set(ph_subsys, h_control,
2648 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0);
2649}
2650
2651u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
2652 u32 h_control, u32 *event_enable)
2653{
2654 return hpi_control_param_get(ph_subsys, h_control,
2655 HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL);
2656}
2657
2658u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
2659 u32 h_control, int threshold)
2660{
2661 return hpi_control_param_set(ph_subsys, h_control,
2662 HPI_TONEDETECTOR_THRESHOLD, (u32)threshold, 0);
2663}
2664
2665u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
2666 u32 h_control, int *threshold)
2667{
2668 return hpi_control_param_get(ph_subsys, h_control,
2669 HPI_TONEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL);
2670}
2671
2672u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
2673 u32 h_control, u32 *state)
2674{
2675 return hpi_control_param_get(ph_subsys, h_control,
2676 HPI_SILENCEDETECTOR_STATE, 0, 0, (u32 *)state, NULL);
2677}
2678
2679u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
2680 u32 h_control, u32 enable)
2681{
2682 return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2683 (u32)enable, 0);
2684}
2685
2686u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
2687 u32 h_control, u32 *enable)
2688{
2689 return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE,
2690 0, 0, (u32 *)enable, NULL);
2691}
2692
2693u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
2694 u32 h_control, u32 event_enable)
2695{
2696 return hpi_control_param_set(ph_subsys, h_control,
2697 HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0);
2698}
2699
2700u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
2701 u32 h_control, u32 *event_enable)
2702{
2703 return hpi_control_param_get(ph_subsys, h_control,
2704 HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL);
2705}
2706
2707u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys,
2708 u32 h_control, u32 delay)
2709{
2710 return hpi_control_param_set(ph_subsys, h_control,
2711 HPI_SILENCEDETECTOR_DELAY, (u32)delay, 0);
2712}
2713
2714u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys,
2715 u32 h_control, u32 *delay)
2716{
2717 return hpi_control_param_get(ph_subsys, h_control,
2718 HPI_SILENCEDETECTOR_DELAY, 0, 0, (u32 *)delay, NULL);
2719}
2720
2721u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
2722 u32 h_control, int threshold)
2723{
2724 return hpi_control_param_set(ph_subsys, h_control,
2725 HPI_SILENCEDETECTOR_THRESHOLD, (u32)threshold, 0);
2726}
2727
2728u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
2729 u32 h_control, int *threshold)
2730{
2731 return hpi_control_param_get(ph_subsys, h_control,
2732 HPI_SILENCEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL);
2733}
2734
2735u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys,
2736 const u32 h_tuner, const u32 index, u16 *pw_band)
2737{
2738 u32 qr;
2739 u16 err;
2740
2741 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0,
2742 &qr);
2743 *pw_band = (u16)qr;
2744 return err;
2745}
2746
2747u16 hpi_tuner_set_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2748 u16 band)
2749{
2750 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_BAND,
2751 band, 0);
2752}
2753
2754u16 hpi_tuner_get_band(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2755 u16 *pw_band)
2756{
2757 u32 band = 0;
2758 u16 error = 0;
2759
2760 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_BAND,
2761 &band);
2762 if (pw_band)
2763 *pw_band = (u16)band;
2764 return error;
2765}
2766
2767u16 hpi_tuner_query_frequency(const struct hpi_hsubsys *ph_subsys,
2768 const u32 h_tuner, const u32 index, const u16 band, u32 *pfreq)
2769{
2770 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_FREQ, index,
2771 band, pfreq);
2772}
2773
2774u16 hpi_tuner_set_frequency(const struct hpi_hsubsys *ph_subsys,
2775 u32 h_control, u32 freq_ink_hz)
2776{
2777 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_FREQ,
2778 freq_ink_hz, 0);
2779}
2780
2781u16 hpi_tuner_get_frequency(const struct hpi_hsubsys *ph_subsys,
2782 u32 h_control, u32 *pw_freq_ink_hz)
2783{
2784 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_FREQ,
2785 pw_freq_ink_hz);
2786}
2787
2788u16 hpi_tuner_query_gain(const struct hpi_hsubsys *ph_subsys,
2789 const u32 h_tuner, const u32 index, u16 *pw_gain)
2790{
2791 u32 qr;
2792 u16 err;
2793
2794 err = hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_BAND, index, 0,
2795 &qr);
2796 *pw_gain = (u16)qr;
2797 return err;
2798}
2799
2800u16 hpi_tuner_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2801 short gain)
2802{
2803 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_GAIN,
2804 gain, 0);
2805}
2806
2807u16 hpi_tuner_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2808 short *pn_gain)
2809{
2810 u32 gain = 0;
2811 u16 error = 0;
2812
2813 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_GAIN,
2814 &gain);
2815 if (pn_gain)
2816 *pn_gain = (u16)gain;
2817 return error;
2818}
2819
2820u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2821 short *pw_level)
2822{
2823 struct hpi_message hm;
2824 struct hpi_response hr;
2825 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2826 HPI_CONTROL_GET_STATE);
2827 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2828 hm.u.c.attribute = HPI_TUNER_LEVEL;
2829 hm.u.c.param1 = HPI_TUNER_LEVEL_AVERAGE;
2830 hpi_send_recv(&hm, &hr);
2831 if (pw_level)
2832 *pw_level = (short)hr.u.c.param1;
2833 return hr.error;
2834}
2835
2836u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys,
2837 u32 h_control, short *pw_level)
2838{
2839 struct hpi_message hm;
2840 struct hpi_response hr;
2841 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2842 HPI_CONTROL_GET_STATE);
2843 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2844 hm.u.c.attribute = HPI_TUNER_LEVEL;
2845 hm.u.c.param1 = HPI_TUNER_LEVEL_RAW;
2846 hpi_send_recv(&hm, &hr);
2847 if (pw_level)
2848 *pw_level = (short)hr.u.c.param1;
2849 return hr.error;
2850}
2851
2852u16 hpi_tuner_query_deemphasis(const struct hpi_hsubsys *ph_subsys,
2853 const u32 h_tuner, const u32 index, const u16 band, u32 *pdeemphasis)
2854{
2855 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_DEEMPHASIS,
2856 index, band, pdeemphasis);
2857}
2858
2859u16 hpi_tuner_set_deemphasis(const struct hpi_hsubsys *ph_subsys,
2860 u32 h_control, u32 deemphasis)
2861{
2862 return hpi_control_param_set(ph_subsys, h_control,
2863 HPI_TUNER_DEEMPHASIS, deemphasis, 0);
2864}
2865
2866u16 hpi_tuner_get_deemphasis(const struct hpi_hsubsys *ph_subsys,
2867 u32 h_control, u32 *pdeemphasis)
2868{
2869 return hpi_control_param1_get(ph_subsys, h_control,
2870 HPI_TUNER_DEEMPHASIS, pdeemphasis);
2871}
2872
2873u16 hpi_tuner_query_program(const struct hpi_hsubsys *ph_subsys,
2874 const u32 h_tuner, u32 *pbitmap_program)
2875{
2876 return hpi_control_query(ph_subsys, h_tuner, HPI_TUNER_PROGRAM, 0, 0,
2877 pbitmap_program);
2878}
2879
2880u16 hpi_tuner_set_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2881 u32 program)
2882{
2883 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_PROGRAM,
2884 program, 0);
2885}
2886
2887u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2888 u32 *pprogram)
2889{
2890 return hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_PROGRAM,
2891 pprogram);
2892}
2893
2894u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys,
2895 u32 h_control, char *psz_dsp_version, const u32 string_size)
2896{
2897 return hpi_control_get_string(ph_subsys, h_control,
2898 HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size);
2899}
2900
2901u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys,
2902 u32 h_control, char *psz_sdk_version, const u32 string_size)
2903{
2904 return hpi_control_get_string(ph_subsys, h_control,
2905 HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size);
2906}
2907
2908u16 hpi_tuner_get_status(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2909 u16 *pw_status_mask, u16 *pw_status)
2910{
2911 u32 status = 0;
2912 u16 error = 0;
2913
2914 error = hpi_control_param1_get(ph_subsys, h_control, HPI_TUNER_STATUS,
2915 &status);
2916 if (pw_status) {
2917 if (!error) {
2918 *pw_status_mask = (u16)(status >> 16);
2919 *pw_status = (u16)(status & 0xFFFF);
2920 } else {
2921 *pw_status_mask = 0;
2922 *pw_status = 0;
2923 }
2924 }
2925 return error;
2926}
2927
2928u16 hpi_tuner_set_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2929 u32 mode, u32 value)
2930{
2931 return hpi_control_param_set(ph_subsys, h_control, HPI_TUNER_MODE,
2932 mode, value);
2933}
2934
2935u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2936 u32 mode, u32 *pn_value)
2937{
2938 return hpi_control_param_get(ph_subsys, h_control, HPI_TUNER_MODE,
2939 mode, 0, pn_value, NULL);
2940}
2941
2942u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys,
2943 u32 h_control, u32 *pquality)
2944{
2945 return hpi_control_param_get(ph_subsys, h_control,
2946 HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL);
2947}
2948
2949u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2950 char *p_data)
2951{
2952 struct hpi_message hm;
2953 struct hpi_response hr;
2954 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
2955 HPI_CONTROL_GET_STATE);
2956 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
2957 hm.u.c.attribute = HPI_TUNER_RDS;
2958 hpi_send_recv(&hm, &hr);
2959 if (p_data) {
2960 *(u32 *)&p_data[0] = hr.u.cu.tuner.rds.data[0];
2961 *(u32 *)&p_data[4] = hr.u.cu.tuner.rds.data[1];
2962 *(u32 *)&p_data[8] = hr.u.cu.tuner.rds.bLER;
2963 }
2964 return hr.error;
2965}
2966
2967u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys,
2968 u32 h_control, char *psz_string, const u32 data_length)
2969{
2970 return hpi_control_get_string(ph_subsys, h_control,
2971 HPI_PAD_CHANNEL_NAME, psz_string, data_length);
2972}
2973
2974u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2975 char *psz_string, const u32 data_length)
2976{
2977 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_ARTIST,
2978 psz_string, data_length);
2979}
2980
2981u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2982 char *psz_string, const u32 data_length)
2983{
2984 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_TITLE,
2985 psz_string, data_length);
2986}
2987
2988u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control,
2989 char *psz_string, const u32 data_length)
2990{
2991 return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_COMMENT,
2992 psz_string, data_length);
2993}
2994
2995u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys,
2996 u32 h_control, u32 *ppTY)
2997{
2998 return hpi_control_param_get(ph_subsys, h_control,
2999 HPI_PAD_PROGRAM_TYPE, 0, 0, ppTY, NULL);
3000}
3001
3002u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3003 u32 *ppI)
3004{
3005 return hpi_control_param_get(ph_subsys, h_control, HPI_PAD_PROGRAM_ID,
3006 0, 0, ppI, NULL);
3007}
3008
3009u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys,
3010 const u32 h_volume, u32 *p_channels)
3011{
3012 return hpi_control_query(ph_subsys, h_volume, HPI_VOLUME_NUM_CHANNELS,
3013 0, 0, p_channels);
3014}
3015
3016u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3017 short an_log_gain[HPI_MAX_CHANNELS]
3018 )
3019{
3020 struct hpi_message hm;
3021 struct hpi_response hr;
3022 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3023 HPI_CONTROL_SET_STATE);
3024 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3025 memcpy(hm.u.c.an_log_value, an_log_gain,
3026 sizeof(short) * HPI_MAX_CHANNELS);
3027 hm.u.c.attribute = HPI_VOLUME_GAIN;
3028
3029 hpi_send_recv(&hm, &hr);
3030
3031 return hr.error;
3032}
3033
3034u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3035 short an_log_gain[HPI_MAX_CHANNELS]
3036 )
3037{
3038 struct hpi_message hm;
3039 struct hpi_response hr;
3040 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3041 HPI_CONTROL_GET_STATE);
3042 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3043 hm.u.c.attribute = HPI_VOLUME_GAIN;
3044
3045 hpi_send_recv(&hm, &hr);
3046
3047 memcpy(an_log_gain, hr.u.c.an_log_value,
3048 sizeof(short) * HPI_MAX_CHANNELS);
3049 return hr.error;
3050}
3051
3052u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3053 short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB)
3054{
3055 struct hpi_message hm;
3056 struct hpi_response hr;
3057 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3058 HPI_CONTROL_GET_STATE);
3059 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3060 hm.u.c.attribute = HPI_VOLUME_RANGE;
3061
3062 hpi_send_recv(&hm, &hr);
3063 if (hr.error) {
3064 hr.u.c.an_log_value[0] = 0;
3065 hr.u.c.an_log_value[1] = 0;
3066 hr.u.c.param1 = 0;
3067 }
3068 if (min_gain_01dB)
3069 *min_gain_01dB = hr.u.c.an_log_value[0];
3070 if (max_gain_01dB)
3071 *max_gain_01dB = hr.u.c.an_log_value[1];
3072 if (step_gain_01dB)
3073 *step_gain_01dB = (short)hr.u.c.param1;
3074 return hr.error;
3075}
3076
3077u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
3078 u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS],
3079 u32 duration_ms, u16 profile)
3080{
3081 struct hpi_message hm;
3082 struct hpi_response hr;
3083 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3084 HPI_CONTROL_SET_STATE);
3085 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3086
3087 memcpy(hm.u.c.an_log_value, an_stop_gain0_01dB,
3088 sizeof(short) * HPI_MAX_CHANNELS);
3089
3090 hm.u.c.attribute = HPI_VOLUME_AUTOFADE;
3091 hm.u.c.param1 = duration_ms;
3092 hm.u.c.param2 = profile;
3093
3094 hpi_send_recv(&hm, &hr);
3095
3096 return hr.error;
3097}
3098
3099u16 hpi_volume_auto_fade(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3100 short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms)
3101{
3102 return hpi_volume_auto_fade_profile(ph_subsys, h_control,
3103 an_stop_gain0_01dB, duration_ms, HPI_VOLUME_AUTOFADE_LOG);
3104}
3105
3106u16 hpi_vox_set_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3107 short an_gain0_01dB)
3108{
3109 struct hpi_message hm;
3110 struct hpi_response hr;
3111 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3112 HPI_CONTROL_SET_STATE);
3113 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3114 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3115
3116 hm.u.c.an_log_value[0] = an_gain0_01dB;
3117
3118 hpi_send_recv(&hm, &hr);
3119
3120 return hr.error;
3121}
3122
3123u16 hpi_vox_get_threshold(const struct hpi_hsubsys *ph_subsys, u32 h_control,
3124 short *an_gain0_01dB)
3125{
3126 struct hpi_message hm;
3127 struct hpi_response hr;
3128 hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
3129 HPI_CONTROL_GET_STATE);
3130 u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
3131 hm.u.c.attribute = HPI_VOX_THRESHOLD;
3132
3133 hpi_send_recv(&hm, &hr);
3134
3135 *an_gain0_01dB = hr.u.c.an_log_value[0];
3136
3137 return hr.error;
3138}
3139
3140static size_t strv_packet_size = MIN_STRV_PACKET_SIZE;
3141
3142static size_t entity_type_to_size[LAST_ENTITY_TYPE] = {
3143 0,
3144 sizeof(struct hpi_entity),
3145 sizeof(void *),
3146
3147 sizeof(int),
3148 sizeof(float),
3149 sizeof(double),
3150
3151 sizeof(char),
3152 sizeof(char),
3153
3154 4 * sizeof(char),
3155 16 * sizeof(char),
3156 6 * sizeof(char),
3157};
3158
3159inline size_t hpi_entity_size(struct hpi_entity *entity_ptr)
3160{
3161 return entity_ptr->header.size;
3162}
3163
3164inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr)
3165{
3166 return sizeof(entity_ptr->header);
3167}
3168
3169inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr)
3170{
3171 return hpi_entity_size(entity_ptr) -
3172 hpi_entity_header_size(entity_ptr);
3173}
3174
3175inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr)
3176{
3177 return hpi_entity_value_size(entity_ptr) /
3178 entity_type_to_size[entity_ptr->header.type];
3179}
3180
3181inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity
3182 *entity_ptr)
3183{
3184 return (void *)(((uint8_t *) entity_ptr) +
3185 hpi_entity_size(entity_ptr));
3186}
3187
3188inline u16 hpi_entity_check_type(const enum e_entity_type t)
3189{
3190 if (t >= 0 && t < STR_TYPE_FIELD_MAX)
3191 return 0;
3192 return HPI_ERROR_ENTITY_TYPE_INVALID;
3193}
3194
3195inline u16 hpi_entity_check_role(const enum e_entity_role r)
3196{
3197 if (r >= 0 && r < STR_ROLE_FIELD_MAX)
3198 return 0;
3199 return HPI_ERROR_ENTITY_ROLE_INVALID;
3200}
3201
3202static u16 hpi_entity_get_next(struct hpi_entity *entity, int recursive_flag,
3203 void *guard_p, struct hpi_entity **next)
3204{
3205 HPI_DEBUG_ASSERT(entity != NULL);
3206 HPI_DEBUG_ASSERT(next != NULL);
3207 HPI_DEBUG_ASSERT(hpi_entity_size(entity) != 0);
3208
3209 if (guard_p <= (void *)entity) {
3210 *next = NULL;
3211 return 0;
3212 }
3213
3214 if (recursive_flag && entity->header.type == entity_type_sequence)
3215 *next = (struct hpi_entity *)entity->value;
3216 else
3217 *next = (struct hpi_entity *)hpi_entity_ptr_to_next(entity);
3218
3219 if (guard_p <= (void *)*next) {
3220 *next = NULL;
3221 return 0;
3222 }
3223
3224 HPI_DEBUG_ASSERT(guard_p >= (void *)hpi_entity_ptr_to_next(*next));
3225 return 0;
3226}
3227
3228u16 hpi_entity_find_next(struct hpi_entity *container_entity,
3229 enum e_entity_type type, enum e_entity_role role, int recursive_flag,
3230 struct hpi_entity **current_match)
3231{
3232 struct hpi_entity *tmp = NULL;
3233 void *guard_p = NULL;
3234
3235 HPI_DEBUG_ASSERT(container_entity != NULL);
3236 guard_p = hpi_entity_ptr_to_next(container_entity);
3237
3238 if (*current_match != NULL)
3239 hpi_entity_get_next(*current_match, recursive_flag, guard_p,
3240 &tmp);
3241 else
3242 hpi_entity_get_next(container_entity, 1, guard_p, &tmp);
3243
3244 while (tmp) {
3245 u16 err;
3246
3247 HPI_DEBUG_ASSERT((void *)tmp >= (void *)container_entity);
3248
3249 if ((!type || tmp->header.type == type) && (!role
3250 || tmp->header.role == role)) {
3251 *current_match = tmp;
3252 return 0;
3253 }
3254
3255 err = hpi_entity_get_next(tmp, recursive_flag, guard_p,
3256 current_match);
3257 if (err)
3258 return err;
3259
3260 tmp = *current_match;
3261 }
3262
3263 *current_match = NULL;
3264 return 0;
3265}
3266
3267void hpi_entity_free(struct hpi_entity *entity)
3268{
3269 if (entity != NULL)
3270 kfree(entity);
3271}
3272
3273static u16 hpi_entity_alloc_and_copy(struct hpi_entity *src,
3274 struct hpi_entity **dst)
3275{
3276 size_t buf_size;
3277 HPI_DEBUG_ASSERT(dst != NULL);
3278 HPI_DEBUG_ASSERT(src != NULL);
3279
3280 buf_size = hpi_entity_size(src);
3281 *dst = kmalloc(buf_size, GFP_KERNEL);
3282 if (*dst == NULL)
3283 return HPI_ERROR_MEMORY_ALLOC;
3284 memcpy(*dst, src, buf_size);
3285 return 0;
3286}
3287
3288u16 hpi_universal_info(const struct hpi_hsubsys *ph_subsys, u32 hC,
3289 struct hpi_entity **info)
3290{
3291 struct hpi_msg_strv hm;
3292 struct hpi_res_strv *phr;
3293 u16 hpi_err;
3294 int remaining_attempts = 2;
3295 size_t resp_packet_size = 1024;
3296
3297 *info = NULL;
3298
3299 while (remaining_attempts--) {
3300 phr = kmalloc(resp_packet_size, GFP_KERNEL);
3301 HPI_DEBUG_ASSERT(phr != NULL);
3302
3303 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3304 (u16)resp_packet_size, HPI_OBJ_CONTROL,
3305 HPI_CONTROL_GET_INFO);
3306 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3307
3308 hm.strv.header.size = sizeof(hm.strv);
3309 phr->strv.header.size = resp_packet_size - sizeof(phr->h);
3310
3311 hpi_send_recv((struct hpi_message *)&hm.h,
3312 (struct hpi_response *)&phr->h);
3313 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3314
3315 HPI_DEBUG_ASSERT(phr->h.specific_error >
3316 MIN_STRV_PACKET_SIZE
3317 && phr->h.specific_error < 1500);
3318 resp_packet_size = phr->h.specific_error;
3319 } else {
3320 remaining_attempts = 0;
3321 if (!phr->h.error)
3322 hpi_entity_alloc_and_copy(&phr->strv, info);
3323 }
3324
3325 hpi_err = phr->h.error;
3326 kfree(phr);
3327 }
3328
3329 return hpi_err;
3330}
3331
3332u16 hpi_universal_get(const struct hpi_hsubsys *ph_subsys, u32 hC,
3333 struct hpi_entity **value)
3334{
3335 struct hpi_msg_strv hm;
3336 struct hpi_res_strv *phr;
3337 u16 hpi_err;
3338 int remaining_attempts = 2;
3339
3340 *value = NULL;
3341
3342 while (remaining_attempts--) {
3343 phr = kmalloc(strv_packet_size, GFP_KERNEL);
3344 if (!phr)
3345 return HPI_ERROR_MEMORY_ALLOC;
3346
3347 hpi_init_message_responseV1(&hm.h, (u16)sizeof(hm), &phr->h,
3348 (u16)strv_packet_size, HPI_OBJ_CONTROL,
3349 HPI_CONTROL_GET_STATE);
3350 u32TOINDEXES(hC, &hm.h.adapter_index, &hm.h.obj_index);
3351
3352 hm.strv.header.size = sizeof(hm.strv);
3353 phr->strv.header.size = strv_packet_size - sizeof(phr->h);
3354
3355 hpi_send_recv((struct hpi_message *)&hm.h,
3356 (struct hpi_response *)&phr->h);
3357 if (phr->h.error == HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL) {
3358
3359 HPI_DEBUG_ASSERT(phr->h.specific_error >
3360 MIN_STRV_PACKET_SIZE
3361 && phr->h.specific_error < 1000);
3362 strv_packet_size = phr->h.specific_error;
3363 } else {
3364 remaining_attempts = 0;
3365 if (!phr->h.error)
3366 hpi_entity_alloc_and_copy(&phr->strv, value);
3367 }
3368
3369 hpi_err = phr->h.error;
3370 kfree(phr);
3371 }
3372
3373 return hpi_err;
3374}
3375
3376u16 hpi_universal_set(const struct hpi_hsubsys *ph_subsys, u32 hC,
3377 struct hpi_entity *value)
3378{
3379 struct hpi_msg_strv *phm;
3380 struct hpi_res_strv hr;
3381
3382 phm = kmalloc(sizeof(phm->h) + value->header.size, GFP_KERNEL);
3383 HPI_DEBUG_ASSERT(phm != NULL);
3384
3385 hpi_init_message_responseV1(&phm->h,
3386 sizeof(phm->h) + value->header.size, &hr.h, sizeof(hr),
3387 HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
3388 u32TOINDEXES(hC, &phm->h.adapter_index, &phm->h.obj_index);
3389 hr.strv.header.size = sizeof(hr.strv);
3390
3391 memcpy(&phm->strv, value, value->header.size);
3392 hpi_send_recv((struct hpi_message *)&phm->h,
3393 (struct hpi_response *)&hr.h);
3394
3395 return hr.h.error;
3396}
3397
3398u16 hpi_entity_alloc_and_pack(const enum e_entity_type type,
3399 const size_t item_count, const enum e_entity_role role, void *value,
3400 struct hpi_entity **entity)
3401{
3402 size_t bytes_to_copy, total_size;
3403 u16 hE = 0;
3404 *entity = NULL;
3405
3406 hE = hpi_entity_check_type(type);
3407 if (hE)
3408 return hE;
3409
3410 HPI_DEBUG_ASSERT(role > entity_role_null && type < LAST_ENTITY_TYPE);
3411
3412 bytes_to_copy = entity_type_to_size[type] * item_count;
3413 total_size = hpi_entity_header_size(*entity) + bytes_to_copy;
3414
3415 HPI_DEBUG_ASSERT(total_size >= hpi_entity_header_size(*entity)
3416 && total_size < STR_SIZE_FIELD_MAX);
3417
3418 *entity = kmalloc(total_size, GFP_KERNEL);
3419 if (*entity == NULL)
3420 return HPI_ERROR_MEMORY_ALLOC;
3421 memcpy((*entity)->value, value, bytes_to_copy);
3422 (*entity)->header.size =
3423 hpi_entity_header_size(*entity) + bytes_to_copy;
3424 (*entity)->header.type = type;
3425 (*entity)->header.role = role;
3426 return 0;
3427}
3428
3429u16 hpi_entity_copy_value_from(struct hpi_entity *entity,
3430 enum e_entity_type type, size_t item_count, void *value_dst_p)
3431{
3432 size_t bytes_to_copy;
3433
3434 if (entity->header.type != type)
3435 return HPI_ERROR_ENTITY_TYPE_MISMATCH;
3436
3437 if (hpi_entity_item_count(entity) != item_count)
3438 return HPI_ERROR_ENTITY_ITEM_COUNT;
3439
3440 bytes_to_copy = entity_type_to_size[type] * item_count;
3441 memcpy(value_dst_p, entity->value, bytes_to_copy);
3442 return 0;
3443}
3444
3445u16 hpi_entity_unpack(struct hpi_entity *entity, enum e_entity_type *type,
3446 size_t *item_count, enum e_entity_role *role, void **value)
3447{
3448 u16 err = 0;
3449 HPI_DEBUG_ASSERT(entity != NULL);
3450
3451 if (type)
3452 *type = entity->header.type;
3453
3454 if (role)
3455 *role = entity->header.role;
3456
3457 if (value)
3458 *value = entity->value;
3459
3460 if (item_count != NULL) {
3461 if (entity->header.type == entity_type_sequence) {
3462 void *guard_p = hpi_entity_ptr_to_next(entity);
3463 struct hpi_entity *next = NULL;
3464 void *contents = entity->value;
3465
3466 *item_count = 0;
3467 while (contents < guard_p) {
3468 (*item_count)++;
3469 err = hpi_entity_get_next(contents, 0,
3470 guard_p, &next);
3471 if (next == NULL || err)
3472 break;
3473 contents = next;
3474 }
3475 } else {
3476 *item_count = hpi_entity_item_count(entity);
3477 }
3478 }
3479 return err;
3480}
3481
3482u16 hpi_gpio_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3483 u32 *ph_gpio, u16 *pw_number_input_bits, u16 *pw_number_output_bits)
3484{
3485 struct hpi_message hm;
3486 struct hpi_response hr;
3487 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_OPEN);
3488 hm.adapter_index = adapter_index;
3489
3490 hpi_send_recv(&hm, &hr);
3491
3492 if (hr.error == 0) {
3493 *ph_gpio =
3494 hpi_indexes_to_handle(HPI_OBJ_GPIO, adapter_index, 0);
3495 if (pw_number_input_bits)
3496 *pw_number_input_bits = hr.u.l.number_input_bits;
3497 if (pw_number_output_bits)
3498 *pw_number_output_bits = hr.u.l.number_output_bits;
3499 } else
3500 *ph_gpio = 0;
3501 return hr.error;
3502}
3503
3504u16 hpi_gpio_read_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3505 u16 bit_index, u16 *pw_bit_data)
3506{
3507 struct hpi_message hm;
3508 struct hpi_response hr;
3509 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_BIT);
3510 u32TOINDEX(h_gpio, &hm.adapter_index);
3511 hm.u.l.bit_index = bit_index;
3512
3513 hpi_send_recv(&hm, &hr);
3514
3515 *pw_bit_data = hr.u.l.bit_data[0];
3516 return hr.error;
3517}
3518
3519u16 hpi_gpio_read_all_bits(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3520 u16 aw_all_bit_data[4]
3521 )
3522{
3523 struct hpi_message hm;
3524 struct hpi_response hr;
3525 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_READ_ALL);
3526 u32TOINDEX(h_gpio, &hm.adapter_index);
3527
3528 hpi_send_recv(&hm, &hr);
3529
3530 if (aw_all_bit_data) {
3531 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3532 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3533 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3534 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3535 }
3536 return hr.error;
3537}
3538
3539u16 hpi_gpio_write_bit(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3540 u16 bit_index, u16 bit_data)
3541{
3542 struct hpi_message hm;
3543 struct hpi_response hr;
3544 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO, HPI_GPIO_WRITE_BIT);
3545 u32TOINDEX(h_gpio, &hm.adapter_index);
3546 hm.u.l.bit_index = bit_index;
3547 hm.u.l.bit_data = bit_data;
3548
3549 hpi_send_recv(&hm, &hr);
3550
3551 return hr.error;
3552}
3553
3554u16 hpi_gpio_write_status(const struct hpi_hsubsys *ph_subsys, u32 h_gpio,
3555 u16 aw_all_bit_data[4]
3556 )
3557{
3558 struct hpi_message hm;
3559 struct hpi_response hr;
3560 hpi_init_message_response(&hm, &hr, HPI_OBJ_GPIO,
3561 HPI_GPIO_WRITE_STATUS);
3562 u32TOINDEX(h_gpio, &hm.adapter_index);
3563
3564 hpi_send_recv(&hm, &hr);
3565
3566 if (aw_all_bit_data) {
3567 aw_all_bit_data[0] = hr.u.l.bit_data[0];
3568 aw_all_bit_data[1] = hr.u.l.bit_data[1];
3569 aw_all_bit_data[2] = hr.u.l.bit_data[2];
3570 aw_all_bit_data[3] = hr.u.l.bit_data[3];
3571 }
3572 return hr.error;
3573}
3574
3575u16 hpi_async_event_open(const struct hpi_hsubsys *ph_subsys,
3576 u16 adapter_index, u32 *ph_async)
3577{
3578 struct hpi_message hm;
3579 struct hpi_response hr;
3580 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3581 HPI_ASYNCEVENT_OPEN);
3582 hm.adapter_index = adapter_index;
3583
3584 hpi_send_recv(&hm, &hr);
3585
3586 if (hr.error == 0)
3587
3588 *ph_async =
3589 hpi_indexes_to_handle(HPI_OBJ_ASYNCEVENT,
3590 adapter_index, 0);
3591 else
3592 *ph_async = 0;
3593 return hr.error;
3594
3595}
3596
3597u16 hpi_async_event_close(const struct hpi_hsubsys *ph_subsys, u32 h_async)
3598{
3599 struct hpi_message hm;
3600 struct hpi_response hr;
3601 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3602 HPI_ASYNCEVENT_OPEN);
3603 u32TOINDEX(h_async, &hm.adapter_index);
3604
3605 hpi_send_recv(&hm, &hr);
3606
3607 return hr.error;
3608}
3609
3610u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3611 u16 maximum_events, struct hpi_async_event *p_events,
3612 u16 *pw_number_returned)
3613{
3614 return 0;
3615}
3616
3617u16 hpi_async_event_get_count(const struct hpi_hsubsys *ph_subsys,
3618 u32 h_async, u16 *pw_count)
3619{
3620 struct hpi_message hm;
3621 struct hpi_response hr;
3622 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3623 HPI_ASYNCEVENT_GETCOUNT);
3624 u32TOINDEX(h_async, &hm.adapter_index);
3625
3626 hpi_send_recv(&hm, &hr);
3627
3628 if (hr.error == 0)
3629 if (pw_count)
3630 *pw_count = hr.u.as.u.count.count;
3631
3632 return hr.error;
3633}
3634
3635u16 hpi_async_event_get(const struct hpi_hsubsys *ph_subsys, u32 h_async,
3636 u16 maximum_events, struct hpi_async_event *p_events,
3637 u16 *pw_number_returned)
3638{
3639 struct hpi_message hm;
3640 struct hpi_response hr;
3641 hpi_init_message_response(&hm, &hr, HPI_OBJ_ASYNCEVENT,
3642 HPI_ASYNCEVENT_GET);
3643 u32TOINDEX(h_async, &hm.adapter_index);
3644
3645 hpi_send_recv(&hm, &hr);
3646 if (!hr.error) {
3647 memcpy(p_events, &hr.u.as.u.event,
3648 sizeof(struct hpi_async_event));
3649 *pw_number_returned = 1;
3650 }
3651
3652 return hr.error;
3653}
3654
3655u16 hpi_nv_memory_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3656 u32 *ph_nv_memory, u16 *pw_size_in_bytes)
3657{
3658 struct hpi_message hm;
3659 struct hpi_response hr;
3660 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3661 HPI_NVMEMORY_OPEN);
3662 hm.adapter_index = adapter_index;
3663
3664 hpi_send_recv(&hm, &hr);
3665
3666 if (hr.error == 0) {
3667 *ph_nv_memory =
3668 hpi_indexes_to_handle(HPI_OBJ_NVMEMORY, adapter_index,
3669 0);
3670 if (pw_size_in_bytes)
3671 *pw_size_in_bytes = hr.u.n.size_in_bytes;
3672 } else
3673 *ph_nv_memory = 0;
3674 return hr.error;
3675}
3676
3677u16 hpi_nv_memory_read_byte(const struct hpi_hsubsys *ph_subsys,
3678 u32 h_nv_memory, u16 index, u16 *pw_data)
3679{
3680 struct hpi_message hm;
3681 struct hpi_response hr;
3682 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3683 HPI_NVMEMORY_READ_BYTE);
3684 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3685 hm.u.n.address = index;
3686
3687 hpi_send_recv(&hm, &hr);
3688
3689 *pw_data = hr.u.n.data;
3690 return hr.error;
3691}
3692
3693u16 hpi_nv_memory_write_byte(const struct hpi_hsubsys *ph_subsys,
3694 u32 h_nv_memory, u16 index, u16 data)
3695{
3696 struct hpi_message hm;
3697 struct hpi_response hr;
3698 hpi_init_message_response(&hm, &hr, HPI_OBJ_NVMEMORY,
3699 HPI_NVMEMORY_WRITE_BYTE);
3700 u32TOINDEX(h_nv_memory, &hm.adapter_index);
3701 hm.u.n.address = index;
3702 hm.u.n.data = data;
3703
3704 hpi_send_recv(&hm, &hr);
3705
3706 return hr.error;
3707}
3708
3709u16 hpi_profile_open_all(const struct hpi_hsubsys *ph_subsys,
3710 u16 adapter_index, u16 profile_index, u32 *ph_profile,
3711 u16 *pw_max_profiles)
3712{
3713 struct hpi_message hm;
3714 struct hpi_response hr;
3715 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3716 HPI_PROFILE_OPEN_ALL);
3717 hm.adapter_index = adapter_index;
3718 hm.obj_index = profile_index;
3719 hpi_send_recv(&hm, &hr);
3720
3721 *pw_max_profiles = hr.u.p.u.o.max_profiles;
3722 if (hr.error == 0)
3723 *ph_profile =
3724 hpi_indexes_to_handle(HPI_OBJ_PROFILE, adapter_index,
3725 profile_index);
3726 else
3727 *ph_profile = 0;
3728 return hr.error;
3729}
3730
3731u16 hpi_profile_get(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3732 u16 bin_index, u16 *pw_seconds, u32 *pmicro_seconds, u32 *pcall_count,
3733 u32 *pmax_micro_seconds, u32 *pmin_micro_seconds)
3734{
3735 struct hpi_message hm;
3736 struct hpi_response hr;
3737 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE, HPI_PROFILE_GET);
3738 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3739 hm.u.p.bin_index = bin_index;
3740 hpi_send_recv(&hm, &hr);
3741 if (pw_seconds)
3742 *pw_seconds = hr.u.p.u.t.seconds;
3743 if (pmicro_seconds)
3744 *pmicro_seconds = hr.u.p.u.t.micro_seconds;
3745 if (pcall_count)
3746 *pcall_count = hr.u.p.u.t.call_count;
3747 if (pmax_micro_seconds)
3748 *pmax_micro_seconds = hr.u.p.u.t.max_micro_seconds;
3749 if (pmin_micro_seconds)
3750 *pmin_micro_seconds = hr.u.p.u.t.min_micro_seconds;
3751 return hr.error;
3752}
3753
3754u16 hpi_profile_get_utilization(const struct hpi_hsubsys *ph_subsys,
3755 u32 h_profile, u32 *putilization)
3756{
3757 struct hpi_message hm;
3758 struct hpi_response hr;
3759 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3760 HPI_PROFILE_GET_UTILIZATION);
3761 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3762 hpi_send_recv(&hm, &hr);
3763 if (hr.error) {
3764 if (putilization)
3765 *putilization = 0;
3766 } else {
3767 if (putilization)
3768 *putilization = hr.u.p.u.t.call_count;
3769 }
3770 return hr.error;
3771}
3772
3773u16 hpi_profile_get_name(const struct hpi_hsubsys *ph_subsys, u32 h_profile,
3774 u16 bin_index, char *sz_name, u16 name_length)
3775{
3776 struct hpi_message hm;
3777 struct hpi_response hr;
3778 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3779 HPI_PROFILE_GET_NAME);
3780 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3781 hm.u.p.bin_index = bin_index;
3782 hpi_send_recv(&hm, &hr);
3783 if (hr.error) {
3784 if (sz_name)
3785 strcpy(sz_name, "??");
3786 } else {
3787 if (sz_name)
3788 memcpy(sz_name, (char *)hr.u.p.u.n.sz_name,
3789 name_length);
3790 }
3791 return hr.error;
3792}
3793
3794u16 hpi_profile_start_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3795{
3796 struct hpi_message hm;
3797 struct hpi_response hr;
3798 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3799 HPI_PROFILE_START_ALL);
3800 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3801 hpi_send_recv(&hm, &hr);
3802
3803 return hr.error;
3804}
3805
3806u16 hpi_profile_stop_all(const struct hpi_hsubsys *ph_subsys, u32 h_profile)
3807{
3808 struct hpi_message hm;
3809 struct hpi_response hr;
3810 hpi_init_message_response(&hm, &hr, HPI_OBJ_PROFILE,
3811 HPI_PROFILE_STOP_ALL);
3812 u32TOINDEXES(h_profile, &hm.adapter_index, &hm.obj_index);
3813 hpi_send_recv(&hm, &hr);
3814
3815 return hr.error;
3816}
3817
3818u16 hpi_watchdog_open(const struct hpi_hsubsys *ph_subsys, u16 adapter_index,
3819 u32 *ph_watchdog)
3820{
3821 struct hpi_message hm;
3822 struct hpi_response hr;
3823 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3824 HPI_WATCHDOG_OPEN);
3825 hm.adapter_index = adapter_index;
3826
3827 hpi_send_recv(&hm, &hr);
3828
3829 if (hr.error == 0)
3830 *ph_watchdog =
3831 hpi_indexes_to_handle(HPI_OBJ_WATCHDOG, adapter_index,
3832 0);
3833 else
3834 *ph_watchdog = 0;
3835 return hr.error;
3836}
3837
3838u16 hpi_watchdog_set_time(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog,
3839 u32 time_millisec)
3840{
3841 struct hpi_message hm;
3842 struct hpi_response hr;
3843 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3844 HPI_WATCHDOG_SET_TIME);
3845 u32TOINDEX(h_watchdog, &hm.adapter_index);
3846 hm.u.w.time_ms = time_millisec;
3847
3848 hpi_send_recv(&hm, &hr);
3849
3850 return hr.error;
3851}
3852
3853u16 hpi_watchdog_ping(const struct hpi_hsubsys *ph_subsys, u32 h_watchdog)
3854{
3855 struct hpi_message hm;
3856 struct hpi_response hr;
3857 hpi_init_message_response(&hm, &hr, HPI_OBJ_WATCHDOG,
3858 HPI_WATCHDOG_PING);
3859 u32TOINDEX(h_watchdog, &hm.adapter_index);
3860
3861 hpi_send_recv(&hm, &hr);
3862
3863 return hr.error;
3864}
diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c
new file mode 100644
index 000000000000..8e1d099ed7e4
--- /dev/null
+++ b/sound/pci/asihpi/hpimsginit.c
@@ -0,0 +1,130 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) Utility functions.
20
21 (C) Copyright AudioScience Inc. 2007
22*******************************************************************************/
23
24#include "hpi_internal.h"
25#include "hpimsginit.h"
26
27/* The actual message size for each object type */
28static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
29/* The actual response size for each object type */
30static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
31/* Flag to enable alternate message type for SSX2 bypass. */
32static u16 gwSSX2_bypass;
33
34/** \internal
35 * Used by ASIO driver to disable SSX2 for a single process
36 * \param phSubSys Pointer to HPI subsystem handle.
37 * \param wBypass New bypass setting 0 = off, nonzero = on
38 * \return Previous bypass setting.
39 */
40u16 hpi_subsys_ssx2_bypass(const struct hpi_hsubsys *ph_subsys, u16 bypass)
41{
42 u16 old_value = gwSSX2_bypass;
43
44 gwSSX2_bypass = bypass;
45
46 return old_value;
47}
48
49/** \internal
50 * initialize the HPI message structure
51 */
52static void hpi_init_message(struct hpi_message *phm, u16 object,
53 u16 function)
54{
55 memset(phm, 0, sizeof(*phm));
56 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
57 phm->size = msg_size[object];
58 else
59 phm->size = sizeof(*phm);
60
61 if (gwSSX2_bypass)
62 phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
63 else
64 phm->type = HPI_TYPE_MESSAGE;
65 phm->object = object;
66 phm->function = function;
67 phm->version = 0;
68 /* Expect adapter index to be set by caller */
69}
70
71/** \internal
72 * initialize the HPI response structure
73 */
74void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
75 u16 error)
76{
77 memset(phr, 0, sizeof(*phr));
78 phr->type = HPI_TYPE_RESPONSE;
79 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
80 phr->size = res_size[object];
81 else
82 phr->size = sizeof(*phr);
83 phr->object = object;
84 phr->function = function;
85 phr->error = error;
86 phr->specific_error = 0;
87 phr->version = 0;
88}
89
90void hpi_init_message_response(struct hpi_message *phm,
91 struct hpi_response *phr, u16 object, u16 function)
92{
93 hpi_init_message(phm, object, function);
94 /* default error return if the response is
95 not filled in by the callee */
96 hpi_init_response(phr, object, function,
97 HPI_ERROR_PROCESSING_MESSAGE);
98}
99
100static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
101 u16 object, u16 function)
102{
103 memset(phm, 0, sizeof(*phm));
104 if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
105 phm->size = size;
106 phm->type = HPI_TYPE_MESSAGE;
107 phm->object = object;
108 phm->function = function;
109 phm->version = 1;
110 /* Expect adapter index to be set by caller */
111 }
112}
113
114void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
115 u16 object, u16 function)
116{
117 memset(phr, 0, sizeof(*phr));
118 phr->size = size;
119 phr->version = 1;
120 phr->type = HPI_TYPE_RESPONSE;
121 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
122}
123
124void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
125 struct hpi_response_header *phr, u16 res_size, u16 object,
126 u16 function)
127{
128 hpi_init_messageV1(phm, msg_size, object, function);
129 hpi_init_responseV1(phr, res_size, object, function);
130}
diff --git a/sound/pci/asihpi/hpimsginit.h b/sound/pci/asihpi/hpimsginit.h
new file mode 100644
index 000000000000..864ad020c9b3
--- /dev/null
+++ b/sound/pci/asihpi/hpimsginit.h
@@ -0,0 +1,40 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Hardware Programming Interface (HPI) Utility functions
20
21 (C) Copyright AudioScience Inc. 2007
22*******************************************************************************/
23/* Initialise response headers, or msg/response pairs.
24Note that it is valid to just init a response e.g. when a lower level is preparing
25a response to a message.
26However, when sending a message, a matching response buffer always must be prepared
27*/
28
29void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
30 u16 error);
31
32void hpi_init_message_response(struct hpi_message *phm,
33 struct hpi_response *phr, u16 object, u16 function);
34
35void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
36 u16 object, u16 function);
37
38void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
39 struct hpi_response_header *phr, u16 res_size, u16 object,
40 u16 function);
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c
new file mode 100644
index 000000000000..2ee90dc3d897
--- /dev/null
+++ b/sound/pci/asihpi/hpimsgx.c
@@ -0,0 +1,907 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Extended Message Function With Response Cacheing
20
21(C) Copyright AudioScience Inc. 2002
22*****************************************************************************/
23#define SOURCEFILE_NAME "hpimsgx.c"
24#include "hpi_internal.h"
25#include "hpimsginit.h"
26#include "hpimsgx.h"
27#include "hpidebug.h"
28
29static struct pci_device_id asihpi_pci_tbl[] = {
30#include "hpipcida.h"
31};
32
33static struct hpios_spinlock msgx_lock;
34
35static hpi_handler_func *hpi_entry_points[HPI_MAX_ADAPTERS];
36
37static hpi_handler_func *hpi_lookup_entry_point_function(const struct hpi_pci
38 *pci_info)
39{
40
41 int i;
42
43 for (i = 0; asihpi_pci_tbl[i].vendor != 0; i++) {
44 if (asihpi_pci_tbl[i].vendor != PCI_ANY_ID
45 && asihpi_pci_tbl[i].vendor != pci_info->vendor_id)
46 continue;
47 if (asihpi_pci_tbl[i].device != PCI_ANY_ID
48 && asihpi_pci_tbl[i].device != pci_info->device_id)
49 continue;
50 if (asihpi_pci_tbl[i].subvendor != PCI_ANY_ID
51 && asihpi_pci_tbl[i].subvendor !=
52 pci_info->subsys_vendor_id)
53 continue;
54 if (asihpi_pci_tbl[i].subdevice != PCI_ANY_ID
55 && asihpi_pci_tbl[i].subdevice !=
56 pci_info->subsys_device_id)
57 continue;
58
59 HPI_DEBUG_LOG(DEBUG, " %x,%lu\n", i,
60 asihpi_pci_tbl[i].driver_data);
61 return (hpi_handler_func *) asihpi_pci_tbl[i].driver_data;
62 }
63
64 return NULL;
65}
66
67static inline void hw_entry_point(struct hpi_message *phm,
68 struct hpi_response *phr)
69{
70
71 hpi_handler_func *ep;
72
73 if (phm->adapter_index < HPI_MAX_ADAPTERS) {
74 ep = (hpi_handler_func *) hpi_entry_points[phm->
75 adapter_index];
76 if (ep) {
77 HPI_DEBUG_MESSAGE(DEBUG, phm);
78 ep(phm, phr);
79 HPI_DEBUG_RESPONSE(phr);
80 return;
81 }
82 }
83 hpi_init_response(phr, phm->object, phm->function,
84 HPI_ERROR_PROCESSING_MESSAGE);
85}
86
87static void adapter_open(struct hpi_message *phm, struct hpi_response *phr);
88static void adapter_close(struct hpi_message *phm, struct hpi_response *phr);
89
90static void mixer_open(struct hpi_message *phm, struct hpi_response *phr);
91static void mixer_close(struct hpi_message *phm, struct hpi_response *phr);
92
93static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
94 void *h_owner);
95static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
96 void *h_owner);
97static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
98 void *h_owner);
99static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
100 void *h_owner);
101
102static void HPIMSGX__reset(u16 adapter_index);
103static u16 HPIMSGX__init(struct hpi_message *phm, struct hpi_response *phr);
104static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner);
105
106#ifndef DISABLE_PRAGMA_PACK1
107#pragma pack(push, 1)
108#endif
109
110struct hpi_subsys_response {
111 struct hpi_response_header h;
112 struct hpi_subsys_res s;
113};
114
115struct hpi_adapter_response {
116 struct hpi_response_header h;
117 struct hpi_adapter_res a;
118};
119
120struct hpi_mixer_response {
121 struct hpi_response_header h;
122 struct hpi_mixer_res m;
123};
124
125struct hpi_stream_response {
126 struct hpi_response_header h;
127 struct hpi_stream_res d;
128};
129
130struct adapter_info {
131 u16 type;
132 u16 num_instreams;
133 u16 num_outstreams;
134};
135
136struct asi_open_state {
137 int open_flag;
138 void *h_owner;
139};
140
141#ifndef DISABLE_PRAGMA_PACK1
142#pragma pack(pop)
143#endif
144
145/* Globals */
146static struct hpi_adapter_response rESP_HPI_ADAPTER_OPEN[HPI_MAX_ADAPTERS];
147
148static struct hpi_stream_response
149 rESP_HPI_OSTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
150
151static struct hpi_stream_response
152 rESP_HPI_ISTREAM_OPEN[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
153
154static struct hpi_mixer_response rESP_HPI_MIXER_OPEN[HPI_MAX_ADAPTERS];
155
156static struct hpi_subsys_response gRESP_HPI_SUBSYS_FIND_ADAPTERS;
157
158static struct adapter_info aDAPTER_INFO[HPI_MAX_ADAPTERS];
159
160/* use these to keep track of opens from user mode apps/DLLs */
161static struct asi_open_state
162 outstream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
163
164static struct asi_open_state
165 instream_user_open[HPI_MAX_ADAPTERS][HPI_MAX_STREAMS];
166
167static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
168 void *h_owner)
169{
170 switch (phm->function) {
171 case HPI_SUBSYS_GET_VERSION:
172 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
173 HPI_SUBSYS_GET_VERSION, 0);
174 phr->u.s.version = HPI_VER >> 8; /* return major.minor */
175 phr->u.s.data = HPI_VER; /* return major.minor.release */
176 break;
177 case HPI_SUBSYS_OPEN:
178 /*do not propagate the message down the chain */
179 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_OPEN, 0);
180 break;
181 case HPI_SUBSYS_CLOSE:
182 /*do not propagate the message down the chain */
183 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CLOSE,
184 0);
185 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
186 break;
187 case HPI_SUBSYS_DRIVER_LOAD:
188 /* Initialize this module's internal state */
189 hpios_msgxlock_init(&msgx_lock);
190 memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
191 hpios_locked_mem_init();
192 /* Init subsys_findadapters response to no-adapters */
193 HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
194 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
195 HPI_SUBSYS_DRIVER_LOAD, 0);
196 /* individual HPIs dont implement driver load */
197 HPI_COMMON(phm, phr);
198 break;
199 case HPI_SUBSYS_DRIVER_UNLOAD:
200 HPI_COMMON(phm, phr);
201 HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
202 hpios_locked_mem_free_all();
203 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
204 HPI_SUBSYS_DRIVER_UNLOAD, 0);
205 return;
206
207 case HPI_SUBSYS_GET_INFO:
208 HPI_COMMON(phm, phr);
209 break;
210
211 case HPI_SUBSYS_FIND_ADAPTERS:
212 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
213 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
214 break;
215 case HPI_SUBSYS_GET_NUM_ADAPTERS:
216 memcpy(phr, &gRESP_HPI_SUBSYS_FIND_ADAPTERS,
217 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
218 phr->function = HPI_SUBSYS_GET_NUM_ADAPTERS;
219 break;
220 case HPI_SUBSYS_GET_ADAPTER:
221 {
222 int count = phm->adapter_index;
223 int index = 0;
224 hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
225 HPI_SUBSYS_GET_ADAPTER, 0);
226
227 /* This is complicated by the fact that we want to
228 * "skip" 0's in the adapter list.
229 * First, make sure we are pointing to a
230 * non-zero adapter type.
231 */
232 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
233 s.aw_adapter_list[index] == 0) {
234 index++;
235 if (index >= HPI_MAX_ADAPTERS)
236 break;
237 }
238 while (count) {
239 /* move on to the next adapter */
240 index++;
241 if (index >= HPI_MAX_ADAPTERS)
242 break;
243 while (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
244 s.aw_adapter_list[index] == 0) {
245 index++;
246 if (index >= HPI_MAX_ADAPTERS)
247 break;
248 }
249 count--;
250 }
251
252 if (index < HPI_MAX_ADAPTERS) {
253 phr->u.s.adapter_index = (u16)index;
254 phr->u.s.aw_adapter_list[0] =
255 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
256 s.aw_adapter_list[index];
257 } else {
258 phr->u.s.adapter_index = 0;
259 phr->u.s.aw_adapter_list[0] = 0;
260 phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER;
261 }
262 break;
263 }
264 case HPI_SUBSYS_CREATE_ADAPTER:
265 HPIMSGX__init(phm, phr);
266 break;
267 case HPI_SUBSYS_DELETE_ADAPTER:
268 HPIMSGX__cleanup(phm->adapter_index, h_owner);
269 {
270 struct hpi_message hm;
271 struct hpi_response hr;
272 /* call to HPI_ADAPTER_CLOSE */
273 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
274 HPI_ADAPTER_CLOSE);
275 hm.adapter_index = phm->adapter_index;
276 hw_entry_point(&hm, &hr);
277 }
278 hw_entry_point(phm, phr);
279 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.
280 aw_adapter_list[phm->adapter_index]
281 = 0;
282 hpi_entry_points[phm->adapter_index] = NULL;
283 break;
284 default:
285 hw_entry_point(phm, phr);
286 break;
287 }
288}
289
290static void adapter_message(struct hpi_message *phm, struct hpi_response *phr,
291 void *h_owner)
292{
293 switch (phm->function) {
294 case HPI_ADAPTER_OPEN:
295 adapter_open(phm, phr);
296 break;
297 case HPI_ADAPTER_CLOSE:
298 adapter_close(phm, phr);
299 break;
300 default:
301 hw_entry_point(phm, phr);
302 break;
303 }
304}
305
306static void mixer_message(struct hpi_message *phm, struct hpi_response *phr)
307{
308 switch (phm->function) {
309 case HPI_MIXER_OPEN:
310 mixer_open(phm, phr);
311 break;
312 case HPI_MIXER_CLOSE:
313 mixer_close(phm, phr);
314 break;
315 default:
316 hw_entry_point(phm, phr);
317 break;
318 }
319}
320
321static void outstream_message(struct hpi_message *phm,
322 struct hpi_response *phr, void *h_owner)
323{
324 if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_outstreams) {
325 hpi_init_response(phr, HPI_OBJ_OSTREAM, phm->function,
326 HPI_ERROR_INVALID_OBJ_INDEX);
327 return;
328 }
329
330 switch (phm->function) {
331 case HPI_OSTREAM_OPEN:
332 outstream_open(phm, phr, h_owner);
333 break;
334 case HPI_OSTREAM_CLOSE:
335 outstream_close(phm, phr, h_owner);
336 break;
337 default:
338 hw_entry_point(phm, phr);
339 break;
340 }
341}
342
343static void instream_message(struct hpi_message *phm,
344 struct hpi_response *phr, void *h_owner)
345{
346 if (phm->obj_index >= aDAPTER_INFO[phm->adapter_index].num_instreams) {
347 hpi_init_response(phr, HPI_OBJ_ISTREAM, phm->function,
348 HPI_ERROR_INVALID_OBJ_INDEX);
349 return;
350 }
351
352 switch (phm->function) {
353 case HPI_ISTREAM_OPEN:
354 instream_open(phm, phr, h_owner);
355 break;
356 case HPI_ISTREAM_CLOSE:
357 instream_close(phm, phr, h_owner);
358 break;
359 default:
360 hw_entry_point(phm, phr);
361 break;
362 }
363}
364
365/* NOTE: HPI_Message() must be defined in the driver as a wrapper for
366 * HPI_MessageEx so that functions in hpifunc.c compile.
367 */
368void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
369 void *h_owner)
370{
371 HPI_DEBUG_MESSAGE(DEBUG, phm);
372
373 if (phm->type != HPI_TYPE_MESSAGE) {
374 hpi_init_response(phr, phm->object, phm->function,
375 HPI_ERROR_INVALID_TYPE);
376 return;
377 }
378
379 if (phm->adapter_index >= HPI_MAX_ADAPTERS
380 && phm->adapter_index != HPIMSGX_ALLADAPTERS) {
381 hpi_init_response(phr, phm->object, phm->function,
382 HPI_ERROR_BAD_ADAPTER_NUMBER);
383 return;
384 }
385
386 switch (phm->object) {
387 case HPI_OBJ_SUBSYSTEM:
388 subsys_message(phm, phr, h_owner);
389 break;
390
391 case HPI_OBJ_ADAPTER:
392 adapter_message(phm, phr, h_owner);
393 break;
394
395 case HPI_OBJ_MIXER:
396 mixer_message(phm, phr);
397 break;
398
399 case HPI_OBJ_OSTREAM:
400 outstream_message(phm, phr, h_owner);
401 break;
402
403 case HPI_OBJ_ISTREAM:
404 instream_message(phm, phr, h_owner);
405 break;
406
407 default:
408 hw_entry_point(phm, phr);
409 break;
410 }
411 HPI_DEBUG_RESPONSE(phr);
412#if 1
413 if (phr->error >= HPI_ERROR_BACKEND_BASE) {
414 void *ep = NULL;
415 char *ep_name;
416
417 HPI_DEBUG_MESSAGE(ERROR, phm);
418
419 if (phm->adapter_index < HPI_MAX_ADAPTERS)
420 ep = hpi_entry_points[phm->adapter_index];
421
422 /* Don't need this? Have adapter index in debug info
423 Know at driver load time index->backend mapping */
424 if (ep == HPI_6000)
425 ep_name = "HPI_6000";
426 else if (ep == HPI_6205)
427 ep_name = "HPI_6205";
428 else
429 ep_name = "unknown";
430
431 HPI_DEBUG_LOG(ERROR, "HPI %s response - error# %d\n", ep_name,
432 phr->error);
433
434 if (hpi_debug_level >= HPI_DEBUG_LEVEL_VERBOSE)
435 hpi_debug_data((u16 *)phm,
436 sizeof(*phm) / sizeof(u16));
437 }
438#endif
439}
440
441static void adapter_open(struct hpi_message *phm, struct hpi_response *phr)
442{
443 HPI_DEBUG_LOG(VERBOSE, "adapter_open\n");
444 memcpy(phr, &rESP_HPI_ADAPTER_OPEN[phm->adapter_index],
445 sizeof(rESP_HPI_ADAPTER_OPEN[0]));
446}
447
448static void adapter_close(struct hpi_message *phm, struct hpi_response *phr)
449{
450 HPI_DEBUG_LOG(VERBOSE, "adapter_close\n");
451 hpi_init_response(phr, HPI_OBJ_ADAPTER, HPI_ADAPTER_CLOSE, 0);
452}
453
454static void mixer_open(struct hpi_message *phm, struct hpi_response *phr)
455{
456 memcpy(phr, &rESP_HPI_MIXER_OPEN[phm->adapter_index],
457 sizeof(rESP_HPI_MIXER_OPEN[0]));
458}
459
460static void mixer_close(struct hpi_message *phm, struct hpi_response *phr)
461{
462 hpi_init_response(phr, HPI_OBJ_MIXER, HPI_MIXER_CLOSE, 0);
463}
464
465static void instream_open(struct hpi_message *phm, struct hpi_response *phr,
466 void *h_owner)
467{
468
469 struct hpi_message hm;
470 struct hpi_response hr;
471
472 hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_OPEN, 0);
473
474 hpios_msgxlock_lock(&msgx_lock);
475
476 if (instream_user_open[phm->adapter_index][phm->obj_index].open_flag)
477 phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
478 else if (rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
479 [phm->obj_index].h.error)
480 memcpy(phr,
481 &rESP_HPI_ISTREAM_OPEN[phm->adapter_index][phm->
482 obj_index],
483 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
484 else {
485 instream_user_open[phm->adapter_index][phm->
486 obj_index].open_flag = 1;
487 hpios_msgxlock_un_lock(&msgx_lock);
488
489 /* issue a reset */
490 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
491 HPI_ISTREAM_RESET);
492 hm.adapter_index = phm->adapter_index;
493 hm.obj_index = phm->obj_index;
494 hw_entry_point(&hm, &hr);
495
496 hpios_msgxlock_lock(&msgx_lock);
497 if (hr.error) {
498 instream_user_open[phm->adapter_index][phm->
499 obj_index].open_flag = 0;
500 phr->error = hr.error;
501 } else {
502 instream_user_open[phm->adapter_index][phm->
503 obj_index].open_flag = 1;
504 instream_user_open[phm->adapter_index][phm->
505 obj_index].h_owner = h_owner;
506 memcpy(phr,
507 &rESP_HPI_ISTREAM_OPEN[phm->adapter_index]
508 [phm->obj_index],
509 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
510 }
511 }
512 hpios_msgxlock_un_lock(&msgx_lock);
513}
514
515static void instream_close(struct hpi_message *phm, struct hpi_response *phr,
516 void *h_owner)
517{
518
519 struct hpi_message hm;
520 struct hpi_response hr;
521
522 hpi_init_response(phr, HPI_OBJ_ISTREAM, HPI_ISTREAM_CLOSE, 0);
523
524 hpios_msgxlock_lock(&msgx_lock);
525 if (h_owner ==
526 instream_user_open[phm->adapter_index][phm->
527 obj_index].h_owner) {
528 /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
529 "instream %d owned by %p\n",
530 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
531 instream_user_open[phm->adapter_index][phm->
532 obj_index].h_owner = NULL;
533 hpios_msgxlock_un_lock(&msgx_lock);
534 /* issue a reset */
535 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
536 HPI_ISTREAM_RESET);
537 hm.adapter_index = phm->adapter_index;
538 hm.obj_index = phm->obj_index;
539 hw_entry_point(&hm, &hr);
540 hpios_msgxlock_lock(&msgx_lock);
541 if (hr.error) {
542 instream_user_open[phm->adapter_index][phm->
543 obj_index].h_owner = h_owner;
544 phr->error = hr.error;
545 } else {
546 instream_user_open[phm->adapter_index][phm->
547 obj_index].open_flag = 0;
548 instream_user_open[phm->adapter_index][phm->
549 obj_index].h_owner = NULL;
550 }
551 } else {
552 HPI_DEBUG_LOG(WARNING,
553 "%p trying to close %d instream %d owned by %p\n",
554 h_owner, phm->adapter_index, phm->obj_index,
555 instream_user_open[phm->adapter_index][phm->
556 obj_index].h_owner);
557 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
558 }
559 hpios_msgxlock_un_lock(&msgx_lock);
560}
561
562static void outstream_open(struct hpi_message *phm, struct hpi_response *phr,
563 void *h_owner)
564{
565
566 struct hpi_message hm;
567 struct hpi_response hr;
568
569 hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_OPEN, 0);
570
571 hpios_msgxlock_lock(&msgx_lock);
572
573 if (outstream_user_open[phm->adapter_index][phm->obj_index].open_flag)
574 phr->error = HPI_ERROR_OBJ_ALREADY_OPEN;
575 else if (rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
576 [phm->obj_index].h.error)
577 memcpy(phr,
578 &rESP_HPI_OSTREAM_OPEN[phm->adapter_index][phm->
579 obj_index],
580 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
581 else {
582 outstream_user_open[phm->adapter_index][phm->
583 obj_index].open_flag = 1;
584 hpios_msgxlock_un_lock(&msgx_lock);
585
586 /* issue a reset */
587 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
588 HPI_OSTREAM_RESET);
589 hm.adapter_index = phm->adapter_index;
590 hm.obj_index = phm->obj_index;
591 hw_entry_point(&hm, &hr);
592
593 hpios_msgxlock_lock(&msgx_lock);
594 if (hr.error) {
595 outstream_user_open[phm->adapter_index][phm->
596 obj_index].open_flag = 0;
597 phr->error = hr.error;
598 } else {
599 outstream_user_open[phm->adapter_index][phm->
600 obj_index].open_flag = 1;
601 outstream_user_open[phm->adapter_index][phm->
602 obj_index].h_owner = h_owner;
603 memcpy(phr,
604 &rESP_HPI_OSTREAM_OPEN[phm->adapter_index]
605 [phm->obj_index],
606 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
607 }
608 }
609 hpios_msgxlock_un_lock(&msgx_lock);
610}
611
612static void outstream_close(struct hpi_message *phm, struct hpi_response *phr,
613 void *h_owner)
614{
615
616 struct hpi_message hm;
617 struct hpi_response hr;
618
619 hpi_init_response(phr, HPI_OBJ_OSTREAM, HPI_OSTREAM_CLOSE, 0);
620
621 hpios_msgxlock_lock(&msgx_lock);
622
623 if (h_owner ==
624 outstream_user_open[phm->adapter_index][phm->
625 obj_index].h_owner) {
626 /* HPI_DEBUG_LOG(INFO,"closing adapter %d "
627 "outstream %d owned by %p\n",
628 phm->wAdapterIndex, phm->wObjIndex, hOwner); */
629 outstream_user_open[phm->adapter_index][phm->
630 obj_index].h_owner = NULL;
631 hpios_msgxlock_un_lock(&msgx_lock);
632 /* issue a reset */
633 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
634 HPI_OSTREAM_RESET);
635 hm.adapter_index = phm->adapter_index;
636 hm.obj_index = phm->obj_index;
637 hw_entry_point(&hm, &hr);
638 hpios_msgxlock_lock(&msgx_lock);
639 if (hr.error) {
640 outstream_user_open[phm->adapter_index][phm->
641 obj_index].h_owner = h_owner;
642 phr->error = hr.error;
643 } else {
644 outstream_user_open[phm->adapter_index][phm->
645 obj_index].open_flag = 0;
646 outstream_user_open[phm->adapter_index][phm->
647 obj_index].h_owner = NULL;
648 }
649 } else {
650 HPI_DEBUG_LOG(WARNING,
651 "%p trying to close %d outstream %d owned by %p\n",
652 h_owner, phm->adapter_index, phm->obj_index,
653 outstream_user_open[phm->adapter_index][phm->
654 obj_index].h_owner);
655 phr->error = HPI_ERROR_OBJ_NOT_OPEN;
656 }
657 hpios_msgxlock_un_lock(&msgx_lock);
658}
659
660static u16 adapter_prepare(u16 adapter)
661{
662 struct hpi_message hm;
663 struct hpi_response hr;
664
665 /* Open the adapter and streams */
666 u16 i;
667
668 /* call to HPI_ADAPTER_OPEN */
669 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
670 HPI_ADAPTER_OPEN);
671 hm.adapter_index = adapter;
672 hw_entry_point(&hm, &hr);
673 memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
674 sizeof(rESP_HPI_ADAPTER_OPEN[0]));
675 if (hr.error)
676 return hr.error;
677
678 /* call to HPI_ADAPTER_GET_INFO */
679 hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
680 HPI_ADAPTER_GET_INFO);
681 hm.adapter_index = adapter;
682 hw_entry_point(&hm, &hr);
683 if (hr.error)
684 return hr.error;
685
686 aDAPTER_INFO[adapter].num_outstreams = hr.u.a.num_outstreams;
687 aDAPTER_INFO[adapter].num_instreams = hr.u.a.num_instreams;
688 aDAPTER_INFO[adapter].type = hr.u.a.adapter_type;
689
690 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list[adapter] =
691 hr.u.a.adapter_type;
692 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters++;
693 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters > HPI_MAX_ADAPTERS)
694 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters =
695 HPI_MAX_ADAPTERS;
696
697 /* call to HPI_OSTREAM_OPEN */
698 for (i = 0; i < aDAPTER_INFO[adapter].num_outstreams; i++) {
699 hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
700 HPI_OSTREAM_OPEN);
701 hm.adapter_index = adapter;
702 hm.obj_index = i;
703 hw_entry_point(&hm, &hr);
704 memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i], &hr,
705 sizeof(rESP_HPI_OSTREAM_OPEN[0][0]));
706 outstream_user_open[adapter][i].open_flag = 0;
707 outstream_user_open[adapter][i].h_owner = NULL;
708 }
709
710 /* call to HPI_ISTREAM_OPEN */
711 for (i = 0; i < aDAPTER_INFO[adapter].num_instreams; i++) {
712 hpi_init_message_response(&hm, &hr, HPI_OBJ_ISTREAM,
713 HPI_ISTREAM_OPEN);
714 hm.adapter_index = adapter;
715 hm.obj_index = i;
716 hw_entry_point(&hm, &hr);
717 memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i], &hr,
718 sizeof(rESP_HPI_ISTREAM_OPEN[0][0]));
719 instream_user_open[adapter][i].open_flag = 0;
720 instream_user_open[adapter][i].h_owner = NULL;
721 }
722
723 /* call to HPI_MIXER_OPEN */
724 hpi_init_message_response(&hm, &hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN);
725 hm.adapter_index = adapter;
726 hw_entry_point(&hm, &hr);
727 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
728 sizeof(rESP_HPI_MIXER_OPEN[0]));
729
730 return gRESP_HPI_SUBSYS_FIND_ADAPTERS.h.error;
731}
732
733static void HPIMSGX__reset(u16 adapter_index)
734{
735 int i;
736 u16 adapter;
737 struct hpi_response hr;
738
739 if (adapter_index == HPIMSGX_ALLADAPTERS) {
740 /* reset all responses to contain errors */
741 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
742 HPI_SUBSYS_FIND_ADAPTERS, 0);
743 memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
744 sizeof(&gRESP_HPI_SUBSYS_FIND_ADAPTERS));
745
746 for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {
747
748 hpi_init_response(&hr, HPI_OBJ_ADAPTER,
749 HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER);
750 memcpy(&rESP_HPI_ADAPTER_OPEN[adapter], &hr,
751 sizeof(rESP_HPI_ADAPTER_OPEN[adapter]));
752
753 hpi_init_response(&hr, HPI_OBJ_MIXER, HPI_MIXER_OPEN,
754 HPI_ERROR_INVALID_OBJ);
755 memcpy(&rESP_HPI_MIXER_OPEN[adapter], &hr,
756 sizeof(rESP_HPI_MIXER_OPEN[adapter]));
757
758 for (i = 0; i < HPI_MAX_STREAMS; i++) {
759 hpi_init_response(&hr, HPI_OBJ_OSTREAM,
760 HPI_OSTREAM_OPEN,
761 HPI_ERROR_INVALID_OBJ);
762 memcpy(&rESP_HPI_OSTREAM_OPEN[adapter][i],
763 &hr,
764 sizeof(rESP_HPI_OSTREAM_OPEN[adapter]
765 [i]));
766 hpi_init_response(&hr, HPI_OBJ_ISTREAM,
767 HPI_ISTREAM_OPEN,
768 HPI_ERROR_INVALID_OBJ);
769 memcpy(&rESP_HPI_ISTREAM_OPEN[adapter][i],
770 &hr,
771 sizeof(rESP_HPI_ISTREAM_OPEN[adapter]
772 [i]));
773 }
774 }
775 } else if (adapter_index < HPI_MAX_ADAPTERS) {
776 rESP_HPI_ADAPTER_OPEN[adapter_index].h.error =
777 HPI_ERROR_BAD_ADAPTER;
778 rESP_HPI_MIXER_OPEN[adapter_index].h.error =
779 HPI_ERROR_INVALID_OBJ;
780 for (i = 0; i < HPI_MAX_STREAMS; i++) {
781 rESP_HPI_OSTREAM_OPEN[adapter_index][i].h.error =
782 HPI_ERROR_INVALID_OBJ;
783 rESP_HPI_ISTREAM_OPEN[adapter_index][i].h.error =
784 HPI_ERROR_INVALID_OBJ;
785 }
786 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.
787 s.aw_adapter_list[adapter_index]) {
788 gRESP_HPI_SUBSYS_FIND_ADAPTERS.
789 s.aw_adapter_list[adapter_index] = 0;
790 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters--;
791 }
792 }
793}
794
795static u16 HPIMSGX__init(struct hpi_message *phm,
796 /* HPI_SUBSYS_CREATE_ADAPTER structure with */
797 /* resource list or NULL=find all */
798 struct hpi_response *phr
799 /* response from HPI_ADAPTER_GET_INFO */
800 )
801{
802 hpi_handler_func *entry_point_func;
803 struct hpi_response hr;
804
805 if (gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.num_adapters >= HPI_MAX_ADAPTERS)
806 return HPI_ERROR_BAD_ADAPTER_NUMBER;
807
808 /* Init response here so we can pass in previous adapter list */
809 hpi_init_response(&hr, phm->object, phm->function,
810 HPI_ERROR_INVALID_OBJ);
811 memcpy(hr.u.s.aw_adapter_list,
812 gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list,
813 sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS.s.aw_adapter_list));
814
815 entry_point_func =
816 hpi_lookup_entry_point_function(phm->u.s.resource.r.pci);
817
818 if (entry_point_func) {
819 HPI_DEBUG_MESSAGE(DEBUG, phm);
820 entry_point_func(phm, &hr);
821 } else {
822 phr->error = HPI_ERROR_PROCESSING_MESSAGE;
823 return phr->error;
824 }
825 if (hr.error == 0) {
826 /* the adapter was created succesfully
827 save the mapping for future use */
828 hpi_entry_points[hr.u.s.adapter_index] = entry_point_func;
829 /* prepare adapter (pre-open streams etc.) */
830 HPI_DEBUG_LOG(DEBUG,
831 "HPI_SUBSYS_CREATE_ADAPTER successful,"
832 " preparing adapter\n");
833 adapter_prepare(hr.u.s.adapter_index);
834 }
835 memcpy(phr, &hr, hr.size);
836 return phr->error;
837}
838
839static void HPIMSGX__cleanup(u16 adapter_index, void *h_owner)
840{
841 int i, adapter, adapter_limit;
842
843 if (!h_owner)
844 return;
845
846 if (adapter_index == HPIMSGX_ALLADAPTERS) {
847 adapter = 0;
848 adapter_limit = HPI_MAX_ADAPTERS;
849 } else {
850 adapter = adapter_index;
851 adapter_limit = adapter + 1;
852 }
853
854 for (; adapter < adapter_limit; adapter++) {
855 /* printk(KERN_INFO "Cleanup adapter #%d\n",wAdapter); */
856 for (i = 0; i < HPI_MAX_STREAMS; i++) {
857 if (h_owner ==
858 outstream_user_open[adapter][i].h_owner) {
859 struct hpi_message hm;
860 struct hpi_response hr;
861
862 HPI_DEBUG_LOG(DEBUG,
863 "close adapter %d ostream %d\n",
864 adapter, i);
865
866 hpi_init_message_response(&hm, &hr,
867 HPI_OBJ_OSTREAM, HPI_OSTREAM_RESET);
868 hm.adapter_index = (u16)adapter;
869 hm.obj_index = (u16)i;
870 hw_entry_point(&hm, &hr);
871
872 hm.function = HPI_OSTREAM_HOSTBUFFER_FREE;
873 hw_entry_point(&hm, &hr);
874
875 hm.function = HPI_OSTREAM_GROUP_RESET;
876 hw_entry_point(&hm, &hr);
877
878 outstream_user_open[adapter][i].open_flag = 0;
879 outstream_user_open[adapter][i].h_owner =
880 NULL;
881 }
882 if (h_owner == instream_user_open[adapter][i].h_owner) {
883 struct hpi_message hm;
884 struct hpi_response hr;
885
886 HPI_DEBUG_LOG(DEBUG,
887 "close adapter %d istream %d\n",
888 adapter, i);
889
890 hpi_init_message_response(&hm, &hr,
891 HPI_OBJ_ISTREAM, HPI_ISTREAM_RESET);
892 hm.adapter_index = (u16)adapter;
893 hm.obj_index = (u16)i;
894 hw_entry_point(&hm, &hr);
895
896 hm.function = HPI_ISTREAM_HOSTBUFFER_FREE;
897 hw_entry_point(&hm, &hr);
898
899 hm.function = HPI_ISTREAM_GROUP_RESET;
900 hw_entry_point(&hm, &hr);
901
902 instream_user_open[adapter][i].open_flag = 0;
903 instream_user_open[adapter][i].h_owner = NULL;
904 }
905 }
906 }
907}
diff --git a/sound/pci/asihpi/hpimsgx.h b/sound/pci/asihpi/hpimsgx.h
new file mode 100644
index 000000000000..fd49e7542a88
--- /dev/null
+++ b/sound/pci/asihpi/hpimsgx.h
@@ -0,0 +1,36 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 HPI Extended Message Handler Functions
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23
24#ifndef _HPIMSGX_H_
25#define _HPIMSGX_H_
26
27#include "hpi_internal.h"
28
29#define HPIMSGX_ALLADAPTERS (0xFFFF)
30
31void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
32 void *h_owner);
33
34#define HPI_MESSAGE_LOWER_LAYER hpi_send_recv_ex
35
36#endif /* _HPIMSGX_H_ */
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
new file mode 100644
index 000000000000..7396ac54e99f
--- /dev/null
+++ b/sound/pci/asihpi/hpioctl.c
@@ -0,0 +1,484 @@
1/*******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Common Linux HPI ioctl and module probe/remove functions
20*******************************************************************************/
21#define SOURCEFILE_NAME "hpioctl.c"
22
23#include "hpi_internal.h"
24#include "hpimsginit.h"
25#include "hpidebug.h"
26#include "hpimsgx.h"
27#include "hpioctl.h"
28
29#include <linux/fs.h>
30#include <linux/slab.h>
31#include <linux/moduleparam.h>
32#include <asm/uaccess.h>
33#include <linux/stringify.h>
34
35#ifdef MODULE_FIRMWARE
36MODULE_FIRMWARE("asihpi/dsp5000.bin");
37MODULE_FIRMWARE("asihpi/dsp6200.bin");
38MODULE_FIRMWARE("asihpi/dsp6205.bin");
39MODULE_FIRMWARE("asihpi/dsp6400.bin");
40MODULE_FIRMWARE("asihpi/dsp6600.bin");
41MODULE_FIRMWARE("asihpi/dsp8700.bin");
42MODULE_FIRMWARE("asihpi/dsp8900.bin");
43#endif
44
45static int prealloc_stream_buf;
46module_param(prealloc_stream_buf, int, S_IRUGO);
47MODULE_PARM_DESC(prealloc_stream_buf,
48 "preallocate size for per-adapter stream buffer");
49
50/* Allow the debug level to be changed after module load.
51 E.g. echo 2 > /sys/module/asihpi/parameters/hpiDebugLevel
52*/
53module_param(hpi_debug_level, int, S_IRUGO | S_IWUSR);
54MODULE_PARM_DESC(hpi_debug_level, "debug verbosity 0..5");
55
56/* List of adapters found */
57static struct hpi_adapter adapters[HPI_MAX_ADAPTERS];
58
59/* Wrapper function to HPI_Message to enable dumping of the
60 message and response types.
61*/
62static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr,
63 struct file *file)
64{
65 int adapter = phm->adapter_index;
66
67 if ((adapter >= HPI_MAX_ADAPTERS || adapter < 0)
68 && (phm->object != HPI_OBJ_SUBSYSTEM))
69 phr->error = HPI_ERROR_INVALID_OBJ_INDEX;
70 else
71 hpi_send_recv_ex(phm, phr, file);
72}
73
74/* This is called from hpifunc.c functions, called by ALSA
75 * (or other kernel process) In this case there is no file descriptor
76 * available for the message cache code
77 */
78void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr)
79{
80 hpi_send_recv_f(phm, phr, HOWNER_KERNEL);
81}
82
83EXPORT_SYMBOL(hpi_send_recv);
84/* for radio-asihpi */
85
86int asihpi_hpi_release(struct file *file)
87{
88 struct hpi_message hm;
89 struct hpi_response hr;
90
91/* HPI_DEBUG_LOG(INFO,"hpi_release file %p, pid %d\n", file, current->pid); */
92 /* close the subsystem just in case the application forgot to. */
93 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
94 HPI_SUBSYS_CLOSE);
95 hpi_send_recv_ex(&hm, &hr, file);
96 return 0;
97}
98
99long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
100{
101 struct hpi_ioctl_linux __user *phpi_ioctl_data;
102 void __user *puhm;
103 void __user *puhr;
104 union hpi_message_buffer_v1 *hm;
105 union hpi_response_buffer_v1 *hr;
106 u16 res_max_size;
107 u32 uncopied_bytes;
108 struct hpi_adapter *pa = NULL;
109 int err = 0;
110
111 if (cmd != HPI_IOCTL_LINUX)
112 return -EINVAL;
113
114 hm = kmalloc(sizeof(*hm), GFP_KERNEL);
115 hr = kmalloc(sizeof(*hr), GFP_KERNEL);
116 if (!hm || !hr) {
117 err = -ENOMEM;
118 goto out;
119 }
120
121 phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
122
123 /* Read the message and response pointers from user space. */
124 get_user(puhm, &phpi_ioctl_data->phm);
125 get_user(puhr, &phpi_ioctl_data->phr);
126
127 /* Now read the message size and data from user space. */
128 get_user(hm->h.size, (u16 __user *)puhm);
129 if (hm->h.size > sizeof(*hm))
130 hm->h.size = sizeof(*hm);
131
132 /*printk(KERN_INFO "message size %d\n", hm->h.wSize); */
133
134 uncopied_bytes = copy_from_user(hm, puhm, hm->h.size);
135 if (uncopied_bytes) {
136 HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
137 err = -EFAULT;
138 goto out;
139 }
140
141 get_user(res_max_size, (u16 __user *)puhr);
142 /* printk(KERN_INFO "user response size %d\n", res_max_size); */
143 if (res_max_size < sizeof(struct hpi_response_header)) {
144 HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size);
145 err = -EFAULT;
146 goto out;
147 }
148
149 pa = &adapters[hm->h.adapter_index];
150 hr->h.size = 0;
151 if (hm->h.object == HPI_OBJ_SUBSYSTEM) {
152 switch (hm->h.function) {
153 case HPI_SUBSYS_CREATE_ADAPTER:
154 case HPI_SUBSYS_DELETE_ADAPTER:
155 /* Application must not use these functions! */
156 hr->h.size = sizeof(hr->h);
157 hr->h.error = HPI_ERROR_INVALID_OPERATION;
158 hr->h.function = hm->h.function;
159 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
160 if (uncopied_bytes)
161 err = -EFAULT;
162 else
163 err = 0;
164 goto out;
165
166 default:
167 hpi_send_recv_f(&hm->m0, &hr->r0, file);
168 }
169 } else {
170 u16 __user *ptr = NULL;
171 u32 size = 0;
172
173 /* -1=no data 0=read from user mem, 1=write to user mem */
174 int wrflag = -1;
175 u32 adapter = hm->h.adapter_index;
176
177 if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) {
178 hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
179 HPI_ADAPTER_OPEN,
180 HPI_ERROR_BAD_ADAPTER_NUMBER);
181
182 uncopied_bytes =
183 copy_to_user(puhr, hr, sizeof(hr->h));
184 if (uncopied_bytes)
185 err = -EFAULT;
186 else
187 err = 0;
188 goto out;
189 }
190
191 if (mutex_lock_interruptible(&adapters[adapter].mutex)) {
192 err = -EINTR;
193 goto out;
194 }
195
196 /* Dig out any pointers embedded in the message. */
197 switch (hm->h.function) {
198 case HPI_OSTREAM_WRITE:
199 case HPI_ISTREAM_READ:{
200 /* Yes, sparse, this is correct. */
201 ptr = (u16 __user *)hm->m0.u.d.u.data.pb_data;
202 size = hm->m0.u.d.u.data.data_size;
203
204 /* Allocate buffer according to application request.
205 ?Is it better to alloc/free for the duration
206 of the transaction?
207 */
208 if (pa->buffer_size < size) {
209 HPI_DEBUG_LOG(DEBUG,
210 "realloc adapter %d stream "
211 "buffer from %zd to %d\n",
212 hm->h.adapter_index,
213 pa->buffer_size, size);
214 if (pa->p_buffer) {
215 pa->buffer_size = 0;
216 vfree(pa->p_buffer);
217 }
218 pa->p_buffer = vmalloc(size);
219 if (pa->p_buffer)
220 pa->buffer_size = size;
221 else {
222 HPI_DEBUG_LOG(ERROR,
223 "HPI could not allocate "
224 "stream buffer size %d\n",
225 size);
226
227 mutex_unlock(&adapters
228 [adapter].mutex);
229 err = -EINVAL;
230 goto out;
231 }
232 }
233
234 hm->m0.u.d.u.data.pb_data = pa->p_buffer;
235 if (hm->h.function == HPI_ISTREAM_READ)
236 /* from card, WRITE to user mem */
237 wrflag = 1;
238 else
239 wrflag = 0;
240 break;
241 }
242
243 default:
244 size = 0;
245 break;
246 }
247
248 if (size && (wrflag == 0)) {
249 uncopied_bytes =
250 copy_from_user(pa->p_buffer, ptr, size);
251 if (uncopied_bytes)
252 HPI_DEBUG_LOG(WARNING,
253 "missed %d of %d "
254 "bytes from user\n", uncopied_bytes,
255 size);
256 }
257
258 hpi_send_recv_f(&hm->m0, &hr->r0, file);
259
260 if (size && (wrflag == 1)) {
261 uncopied_bytes =
262 copy_to_user(ptr, pa->p_buffer, size);
263 if (uncopied_bytes)
264 HPI_DEBUG_LOG(WARNING,
265 "missed %d of %d " "bytes to user\n",
266 uncopied_bytes, size);
267 }
268
269 mutex_unlock(&adapters[adapter].mutex);
270 }
271
272 /* on return response size must be set */
273 /*printk(KERN_INFO "response size %d\n", hr->h.wSize); */
274
275 if (!hr->h.size) {
276 HPI_DEBUG_LOG(ERROR, "response zero size\n");
277 err = -EFAULT;
278 goto out;
279 }
280
281 if (hr->h.size > res_max_size) {
282 HPI_DEBUG_LOG(ERROR, "response too big %d %d\n", hr->h.size,
283 res_max_size);
284 /*HPI_DEBUG_MESSAGE(ERROR, hm); */
285 err = -EFAULT;
286 goto out;
287 }
288
289 uncopied_bytes = copy_to_user(puhr, hr, hr->h.size);
290 if (uncopied_bytes) {
291 HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
292 err = -EFAULT;
293 goto out;
294 }
295
296out:
297 kfree(hm);
298 kfree(hr);
299 return err;
300}
301
302int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
303 const struct pci_device_id *pci_id)
304{
305 int err, idx, nm;
306 unsigned int memlen;
307 struct hpi_message hm;
308 struct hpi_response hr;
309 struct hpi_adapter adapter;
310 struct hpi_pci pci;
311
312 memset(&adapter, 0, sizeof(adapter));
313
314 printk(KERN_DEBUG "probe PCI device (%04x:%04x,%04x:%04x,%04x)\n",
315 pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor,
316 pci_dev->subsystem_device, pci_dev->devfn);
317
318 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
319 HPI_SUBSYS_CREATE_ADAPTER);
320 hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM, HPI_SUBSYS_CREATE_ADAPTER,
321 HPI_ERROR_PROCESSING_MESSAGE);
322
323 hm.adapter_index = -1; /* an invalid index */
324
325 /* fill in HPI_PCI information from kernel provided information */
326 adapter.pci = pci_dev;
327
328 nm = HPI_MAX_ADAPTER_MEM_SPACES;
329
330 for (idx = 0; idx < nm; idx++) {
331 HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n",
332 idx, pci_dev->resource[idx].name,
333 (unsigned long long)pci_resource_start(pci_dev, idx),
334 (unsigned long long)pci_resource_end(pci_dev, idx),
335 (unsigned long long)pci_resource_flags(pci_dev, idx));
336
337 if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) {
338 memlen = pci_resource_len(pci_dev, idx);
339 adapter.ap_remapped_mem_base[idx] =
340 ioremap(pci_resource_start(pci_dev, idx),
341 memlen);
342 if (!adapter.ap_remapped_mem_base[idx]) {
343 HPI_DEBUG_LOG(ERROR,
344 "ioremap failed, aborting\n");
345 /* unmap previously mapped pci mem space */
346 goto err;
347 }
348 }
349
350 pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx];
351 }
352
353 /* could replace Pci with direct pointer to pci_dev for linux
354 Instead wrap accessor functions for IDs etc.
355 Would it work for windows?
356 */
357 pci.bus_number = pci_dev->bus->number;
358 pci.vendor_id = (u16)pci_dev->vendor;
359 pci.device_id = (u16)pci_dev->device;
360 pci.subsys_vendor_id = (u16)(pci_dev->subsystem_vendor & 0xffff);
361 pci.subsys_device_id = (u16)(pci_dev->subsystem_device & 0xffff);
362 pci.device_number = pci_dev->devfn;
363 pci.interrupt = pci_dev->irq;
364 pci.p_os_data = pci_dev;
365
366 hm.u.s.resource.bus_type = HPI_BUS_PCI;
367 hm.u.s.resource.r.pci = &pci;
368
369 /* call CreateAdapterObject on the relevant hpi module */
370 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
371 if (hr.error)
372 goto err;
373
374 if (prealloc_stream_buf) {
375 adapter.p_buffer = vmalloc(prealloc_stream_buf);
376 if (!adapter.p_buffer) {
377 HPI_DEBUG_LOG(ERROR,
378 "HPI could not allocate "
379 "kernel buffer size %d\n",
380 prealloc_stream_buf);
381 goto err;
382 }
383 }
384
385 adapter.index = hr.u.s.adapter_index;
386 adapter.type = hr.u.s.aw_adapter_list[adapter.index];
387 hm.adapter_index = adapter.index;
388
389 err = hpi_adapter_open(NULL, adapter.index);
390 if (err)
391 goto err;
392
393 adapter.snd_card_asihpi = NULL;
394 /* WARNING can't init mutex in 'adapter'
395 * and then copy it to adapters[] ?!?!
396 */
397 adapters[hr.u.s.adapter_index] = adapter;
398 mutex_init(&adapters[adapter.index].mutex);
399 pci_set_drvdata(pci_dev, &adapters[adapter.index]);
400
401 printk(KERN_INFO "probe found adapter ASI%04X HPI index #%d.\n",
402 adapter.type, adapter.index);
403
404 return 0;
405
406err:
407 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
408 if (adapter.ap_remapped_mem_base[idx]) {
409 iounmap(adapter.ap_remapped_mem_base[idx]);
410 adapter.ap_remapped_mem_base[idx] = NULL;
411 }
412 }
413
414 if (adapter.p_buffer) {
415 adapter.buffer_size = 0;
416 vfree(adapter.p_buffer);
417 }
418
419 HPI_DEBUG_LOG(ERROR, "adapter_probe failed\n");
420 return -ENODEV;
421}
422
423void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
424{
425 int idx;
426 struct hpi_message hm;
427 struct hpi_response hr;
428 struct hpi_adapter *pa;
429 pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev);
430
431 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
432 HPI_SUBSYS_DELETE_ADAPTER);
433 hm.adapter_index = pa->index;
434 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
435
436 /* unmap PCI memory space, mapped during device init. */
437 for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) {
438 if (pa->ap_remapped_mem_base[idx]) {
439 iounmap(pa->ap_remapped_mem_base[idx]);
440 pa->ap_remapped_mem_base[idx] = NULL;
441 }
442 }
443
444 if (pa->p_buffer) {
445 pa->buffer_size = 0;
446 vfree(pa->p_buffer);
447 }
448
449 pci_set_drvdata(pci_dev, NULL);
450 /*
451 printk(KERN_INFO "PCI device (%04x:%04x,%04x:%04x,%04x),"
452 " HPI index # %d, removed.\n",
453 pci_dev->vendor, pci_dev->device,
454 pci_dev->subsystem_vendor,
455 pci_dev->subsystem_device, pci_dev->devfn,
456 pa->index);
457 */
458}
459
460void __init asihpi_init(void)
461{
462 struct hpi_message hm;
463 struct hpi_response hr;
464
465 memset(adapters, 0, sizeof(adapters));
466
467 printk(KERN_INFO "ASIHPI driver %d.%02d.%02d\n",
468 HPI_VER_MAJOR(HPI_VER), HPI_VER_MINOR(HPI_VER),
469 HPI_VER_RELEASE(HPI_VER));
470
471 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
472 HPI_SUBSYS_DRIVER_LOAD);
473 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
474}
475
476void asihpi_exit(void)
477{
478 struct hpi_message hm;
479 struct hpi_response hr;
480
481 hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
482 HPI_SUBSYS_DRIVER_UNLOAD);
483 hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
484}
diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h
new file mode 100644
index 000000000000..847f72f03fe1
--- /dev/null
+++ b/sound/pci/asihpi/hpioctl.h
@@ -0,0 +1,38 @@
1/*******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19Linux HPI ioctl, and shared module init functions
20*******************************************************************************/
21
22int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
23 const struct pci_device_id *pci_id);
24void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev);
25void __init asihpi_init(void);
26void __exit asihpi_exit(void);
27
28int asihpi_hpi_release(struct file *file);
29
30long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
31
32/* This is called from hpifunc.c functions, called by ALSA
33 * (or other kernel process) In this case there is no file descriptor
34 * available for the message cache code
35 */
36void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr);
37
38#define HOWNER_KERNEL ((void *)-1)
diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c
new file mode 100644
index 000000000000..de615cfdb950
--- /dev/null
+++ b/sound/pci/asihpi/hpios.c
@@ -0,0 +1,114 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI Operating System function implementation for Linux
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23#define SOURCEFILE_NAME "hpios.c"
24#include "hpi_internal.h"
25#include "hpidebug.h"
26#include <linux/delay.h>
27#include <linux/sched.h>
28
29void hpios_delay_micro_seconds(u32 num_micro_sec)
30{
31 if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) {
32 /* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */
33 schedule_timeout_uninterruptible(usecs_to_jiffies
34 (num_micro_sec));
35 } else if (num_micro_sec <= 2000)
36 udelay(num_micro_sec);
37 else
38 mdelay(num_micro_sec / 1000);
39
40}
41
42void hpios_locked_mem_init(void)
43{
44}
45
46/** Allocated an area of locked memory for bus master DMA operations.
47
48On error, return -ENOMEM, and *pMemArea.size = 0
49*/
50u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
51 struct pci_dev *pdev)
52{
53 /*?? any benefit in using managed dmam_alloc_coherent? */
54 p_mem_area->vaddr =
55 dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle,
56 GFP_DMA32 | GFP_KERNEL);
57
58 if (p_mem_area->vaddr) {
59 HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n",
60 size, (unsigned int)p_mem_area->dma_handle,
61 p_mem_area->vaddr);
62 p_mem_area->pdev = &pdev->dev;
63 p_mem_area->size = size;
64 return 0;
65 } else {
66 HPI_DEBUG_LOG(WARNING,
67 "failed to allocate %d bytes locked memory\n", size);
68 p_mem_area->size = 0;
69 return -ENOMEM;
70 }
71}
72
73u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
74{
75 if (p_mem_area->size) {
76 dma_free_coherent(p_mem_area->pdev, p_mem_area->size,
77 p_mem_area->vaddr, p_mem_area->dma_handle);
78 HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n",
79 (unsigned long)p_mem_area->size,
80 (unsigned int)p_mem_area->dma_handle,
81 p_mem_area->vaddr);
82 p_mem_area->size = 0;
83 return 0;
84 } else {
85 return 1;
86 }
87}
88
89void hpios_locked_mem_free_all(void)
90{
91}
92
93void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx,
94 unsigned int length)
95{
96 HPI_DEBUG_LOG(DEBUG, "mapping %d %s %08llx-%08llx %04llx len 0x%x\n",
97 idx, pci_dev->resource[idx].name,
98 (unsigned long long)pci_resource_start(pci_dev, idx),
99 (unsigned long long)pci_resource_end(pci_dev, idx),
100 (unsigned long long)pci_resource_flags(pci_dev, idx), length);
101
102 if (!(pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM)) {
103 HPI_DEBUG_LOG(ERROR, "not an io memory resource\n");
104 return NULL;
105 }
106
107 if (length > pci_resource_len(pci_dev, idx)) {
108 HPI_DEBUG_LOG(ERROR, "resource too small for requested %d \n",
109 length);
110 return NULL;
111 }
112
113 return ioremap(pci_resource_start(pci_dev, idx), length);
114}
diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h
new file mode 100644
index 000000000000..a62c3f1e5f09
--- /dev/null
+++ b/sound/pci/asihpi/hpios.h
@@ -0,0 +1,178 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19HPI Operating System Specific macros for Linux Kernel driver
20
21(C) Copyright AudioScience Inc. 1997-2003
22******************************************************************************/
23#ifndef _HPIOS_H_
24#define _HPIOS_H_
25
26#undef HPI_OS_LINUX_KERNEL
27#define HPI_OS_LINUX_KERNEL
28
29#define HPI_OS_DEFINED
30#define HPI_KERNEL_MODE
31
32#define HPI_REASSIGN_DUPLICATE_ADAPTER_IDX
33
34#include <linux/io.h>
35#include <asm/system.h>
36#include <linux/ioctl.h>
37#include <linux/kernel.h>
38#include <linux/string.h>
39#include <linux/device.h>
40#include <linux/firmware.h>
41#include <linux/interrupt.h>
42#include <linux/pci.h>
43
44#define HPI_NO_OS_FILE_OPS
45
46#ifdef CONFIG_64BIT
47#define HPI64BIT
48#endif
49
50/** Details of a memory area allocated with pci_alloc_consistent
51Need all info for parameters to pci_free_consistent
52*/
53struct consistent_dma_area {
54 struct device *pdev;
55 /* looks like dma-mapping dma_devres ?! */
56 size_t size;
57 void *vaddr;
58 dma_addr_t dma_handle;
59};
60
61static inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
62 *locked_mem_handle, u32 *p_physical_addr)
63{
64 *p_physical_addr = locked_mem_handle->dma_handle;
65 return 0;
66}
67
68static inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
69 *locked_mem_handle, void **pp_virtual_addr)
70{
71 *pp_virtual_addr = locked_mem_handle->vaddr;
72 return 0;
73}
74
75static inline u16 hpios_locked_mem_valid(struct consistent_dma_area
76 *locked_mem_handle)
77{
78 return locked_mem_handle->size != 0;
79}
80
81struct hpi_ioctl_linux {
82 void __user *phm;
83 void __user *phr;
84};
85
86/* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
87 and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is ununsed command
88*/
89#define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
90
91#define HPI_DEBUG_FLAG_ERROR KERN_ERR
92#define HPI_DEBUG_FLAG_WARNING KERN_WARNING
93#define HPI_DEBUG_FLAG_NOTICE KERN_NOTICE
94#define HPI_DEBUG_FLAG_INFO KERN_INFO
95#define HPI_DEBUG_FLAG_DEBUG KERN_DEBUG
96#define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG /* kernel has no verbose */
97
98#include <linux/spinlock.h>
99
100#define HPI_LOCKING
101
102struct hpios_spinlock {
103 spinlock_t lock; /* SEE hpios_spinlock */
104 int lock_context;
105};
106
107/* The reason for all this evilness is that ALSA calls some of a drivers
108 * operators in atomic context, and some not. But all our functions channel
109 * through the HPI_Message conduit, so we can't handle the different context
110 * per function
111 */
112#define IN_LOCK_BH 1
113#define IN_LOCK_IRQ 0
114static inline void cond_lock(struct hpios_spinlock *l)
115{
116 if (irqs_disabled()) {
117 /* NO bh or isr can execute on this processor,
118 so ordinary lock will do
119 */
120 spin_lock(&((l)->lock));
121 l->lock_context = IN_LOCK_IRQ;
122 } else {
123 spin_lock_bh(&((l)->lock));
124 l->lock_context = IN_LOCK_BH;
125 }
126}
127
128static inline void cond_unlock(struct hpios_spinlock *l)
129{
130 if (l->lock_context == IN_LOCK_BH)
131 spin_unlock_bh(&((l)->lock));
132 else
133 spin_unlock(&((l)->lock));
134}
135
136#define hpios_msgxlock_init(obj) spin_lock_init(&(obj)->lock)
137#define hpios_msgxlock_lock(obj) cond_lock(obj)
138#define hpios_msgxlock_un_lock(obj) cond_unlock(obj)
139
140#define hpios_dsplock_init(obj) spin_lock_init(&(obj)->dsp_lock.lock)
141#define hpios_dsplock_lock(obj) cond_lock(&(obj)->dsp_lock)
142#define hpios_dsplock_unlock(obj) cond_unlock(&(obj)->dsp_lock)
143
144#ifdef CONFIG_SND_DEBUG
145#define HPI_DEBUG
146#endif
147
148#define HPI_ALIST_LOCKING
149#define hpios_alistlock_init(obj) spin_lock_init(&((obj)->list_lock.lock))
150#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
151#define hpios_alistlock_un_lock(obj) spin_unlock(&((obj)->list_lock.lock))
152
153struct hpi_adapter {
154 /* mutex prevents contention for one card
155 between multiple user programs (via ioctl) */
156 struct mutex mutex;
157 u16 index;
158 u16 type;
159
160 /* ALSA card structure */
161 void *snd_card_asihpi;
162
163 char *p_buffer;
164 size_t buffer_size;
165 struct pci_dev *pci;
166 void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
167};
168
169static inline void hpios_unmap_io(void __iomem *addr,
170 unsigned long size)
171{
172 iounmap(addr);
173}
174
175void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx,
176 unsigned int length);
177
178#endif
diff --git a/sound/pci/asihpi/hpipcida.h b/sound/pci/asihpi/hpipcida.h
new file mode 100644
index 000000000000..bb30868ce1a3
--- /dev/null
+++ b/sound/pci/asihpi/hpipcida.h
@@ -0,0 +1,37 @@
1/******************************************************************************
2
3 AudioScience HPI driver
4 Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of version 2 of the GNU General Public License as
8 published by the Free Software Foundation;
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 Array initializer for PCI card IDs
20
21(C) Copyright AudioScience Inc. 1998-2003
22*******************************************************************************/
23
24/*NOTE: when adding new lines to this header file
25 they MUST be grouped by HPI entry point.
26*/
27
28{
29HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
30 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
31 (kernel_ulong_t) HPI_6205}
32, {
33HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
34 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
35 (kernel_ulong_t) HPI_6000}
36, {
370}
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 9edc65059e3e..6772070ed492 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1139,40 +1139,28 @@ static void snd_cs4281_proc_read(struct snd_info_entry *entry,
1139 snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq); 1139 snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq);
1140} 1140}
1141 1141
1142static long snd_cs4281_BA0_read(struct snd_info_entry *entry, 1142static ssize_t snd_cs4281_BA0_read(struct snd_info_entry *entry,
1143 void *file_private_data, 1143 void *file_private_data,
1144 struct file *file, char __user *buf, 1144 struct file *file, char __user *buf,
1145 unsigned long count, unsigned long pos) 1145 size_t count, loff_t pos)
1146{ 1146{
1147 long size;
1148 struct cs4281 *chip = entry->private_data; 1147 struct cs4281 *chip = entry->private_data;
1149 1148
1150 size = count; 1149 if (copy_to_user_fromio(buf, chip->ba0 + pos, count))
1151 if (pos + size > CS4281_BA0_SIZE) 1150 return -EFAULT;
1152 size = (long)CS4281_BA0_SIZE - pos; 1151 return count;
1153 if (size > 0) {
1154 if (copy_to_user_fromio(buf, chip->ba0 + pos, size))
1155 return -EFAULT;
1156 }
1157 return size;
1158} 1152}
1159 1153
1160static long snd_cs4281_BA1_read(struct snd_info_entry *entry, 1154static ssize_t snd_cs4281_BA1_read(struct snd_info_entry *entry,
1161 void *file_private_data, 1155 void *file_private_data,
1162 struct file *file, char __user *buf, 1156 struct file *file, char __user *buf,
1163 unsigned long count, unsigned long pos) 1157 size_t count, loff_t pos)
1164{ 1158{
1165 long size;
1166 struct cs4281 *chip = entry->private_data; 1159 struct cs4281 *chip = entry->private_data;
1167 1160
1168 size = count; 1161 if (copy_to_user_fromio(buf, chip->ba1 + pos, count))
1169 if (pos + size > CS4281_BA1_SIZE) 1162 return -EFAULT;
1170 size = (long)CS4281_BA1_SIZE - pos; 1163 return count;
1171 if (size > 0) {
1172 if (copy_to_user_fromio(buf, chip->ba1 + pos, size))
1173 return -EFAULT;
1174 }
1175 return size;
1176} 1164}
1177 1165
1178static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = { 1166static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = {
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 3f99a5e8528c..aad37082cb6e 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2657,21 +2657,16 @@ static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
2657 * proc interface 2657 * proc interface
2658 */ 2658 */
2659 2659
2660static long snd_cs46xx_io_read(struct snd_info_entry *entry, void *file_private_data, 2660static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry,
2661 struct file *file, char __user *buf, 2661 void *file_private_data,
2662 unsigned long count, unsigned long pos) 2662 struct file *file, char __user *buf,
2663 size_t count, loff_t pos)
2663{ 2664{
2664 long size;
2665 struct snd_cs46xx_region *region = entry->private_data; 2665 struct snd_cs46xx_region *region = entry->private_data;
2666 2666
2667 size = count; 2667 if (copy_to_user_fromio(buf, region->remap_addr + pos, count))
2668 if (pos + (size_t)size > region->size) 2668 return -EFAULT;
2669 size = region->size - pos; 2669 return count;
2670 if (size > 0) {
2671 if (copy_to_user_fromio(buf, region->remap_addr + pos, size))
2672 return -EFAULT;
2673 }
2674 return size;
2675} 2670}
2676 2671
2677static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = { 2672static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = {
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index f18bd6207c50..66c7fb3ced3e 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1787,7 +1787,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1787 else if (subsystem) 1787 else if (subsystem)
1788 snd_printdd("Sound card name = %s, " 1788 snd_printdd("Sound card name = %s, "
1789 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. " 1789 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. "
1790 "Forced to subsytem = 0x%x\n", c->name, 1790 "Forced to subsystem = 0x%x\n", c->name,
1791 pci->vendor, pci->device, emu->serial, c->subsystem); 1791 pci->vendor, pci->device, emu->serial, c->subsystem);
1792 else 1792 else
1793 snd_printdd("Sound card name = %s, " 1793 snd_printdd("Sound card name = %s, "
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index baa7cd508cd8..bc38dd4d071f 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -341,15 +341,17 @@ static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry,
341#define TOTAL_SIZE_CODE (0x200*8) 341#define TOTAL_SIZE_CODE (0x200*8)
342#define A_TOTAL_SIZE_CODE (0x400*8) 342#define A_TOTAL_SIZE_CODE (0x400*8)
343 343
344static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry, 344static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
345 void *file_private_data, 345 void *file_private_data,
346 struct file *file, char __user *buf, 346 struct file *file, char __user *buf,
347 unsigned long count, unsigned long pos) 347 size_t count, loff_t pos)
348{ 348{
349 long size;
350 struct snd_emu10k1 *emu = entry->private_data; 349 struct snd_emu10k1 *emu = entry->private_data;
351 unsigned int offset; 350 unsigned int offset;
352 int tram_addr = 0; 351 int tram_addr = 0;
352 unsigned int *tmp;
353 long res;
354 unsigned int idx;
353 355
354 if (!strcmp(entry->name, "fx8010_tram_addr")) { 356 if (!strcmp(entry->name, "fx8010_tram_addr")) {
355 offset = TANKMEMADDRREGBASE; 357 offset = TANKMEMADDRREGBASE;
@@ -361,30 +363,25 @@ static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
361 } else { 363 } else {
362 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE; 364 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
363 } 365 }
364 size = count; 366
365 if (pos + size > entry->size) 367 tmp = kmalloc(count + 8, GFP_KERNEL);
366 size = (long)entry->size - pos; 368 if (!tmp)
367 if (size > 0) { 369 return -ENOMEM;
368 unsigned int *tmp; 370 for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) {
369 long res; 371 unsigned int val;
370 unsigned int idx; 372 val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
371 if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL) 373 if (tram_addr && emu->audigy) {
372 return -ENOMEM; 374 val >>= 11;
373 for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++) 375 val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
374 if (tram_addr && emu->audigy) {
375 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
376 tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
377 } else
378 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
379 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
380 res = -EFAULT;
381 else {
382 res = size;
383 } 376 }
384 kfree(tmp); 377 tmp[idx] = val;
385 return res;
386 } 378 }
387 return 0; 379 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count))
380 res = -EFAULT;
381 else
382 res = count;
383 kfree(tmp);
384 return res;
388} 385}
389 386
390static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, 387static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ecaea9fb48ec..23a58f0d6cb9 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -104,6 +104,7 @@
104#include <linux/gameport.h> 104#include <linux/gameport.h>
105#include <linux/moduleparam.h> 105#include <linux/moduleparam.h>
106#include <linux/mutex.h> 106#include <linux/mutex.h>
107#include <linux/input.h>
107 108
108#include <sound/core.h> 109#include <sound/core.h>
109#include <sound/pcm.h> 110#include <sound/pcm.h>
@@ -517,14 +518,9 @@ struct es1968 {
517 518
518 /* ALSA Stuff */ 519 /* ALSA Stuff */
519 struct snd_ac97 *ac97; 520 struct snd_ac97 *ac97;
520 struct snd_kcontrol *master_switch; /* for h/w volume control */
521 struct snd_kcontrol *master_volume;
522
523 struct snd_rawmidi *rmidi; 521 struct snd_rawmidi *rmidi;
524 522
525 spinlock_t reg_lock; 523 spinlock_t reg_lock;
526 spinlock_t ac97_lock;
527 struct tasklet_struct hwvol_tq;
528 unsigned int in_suspend; 524 unsigned int in_suspend;
529 525
530 /* Maestro Stuff */ 526 /* Maestro Stuff */
@@ -547,6 +543,16 @@ struct es1968 {
547#ifdef SUPPORT_JOYSTICK 543#ifdef SUPPORT_JOYSTICK
548 struct gameport *gameport; 544 struct gameport *gameport;
549#endif 545#endif
546
547#ifdef CONFIG_SND_ES1968_INPUT
548 struct input_dev *input_dev;
549 char phys[64]; /* physical device path */
550#else
551 struct snd_kcontrol *master_switch; /* for h/w volume control */
552 struct snd_kcontrol *master_volume;
553 spinlock_t ac97_lock;
554 struct tasklet_struct hwvol_tq;
555#endif
550}; 556};
551 557
552static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); 558static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
@@ -632,28 +638,38 @@ static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
632static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 638static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
633{ 639{
634 struct es1968 *chip = ac97->private_data; 640 struct es1968 *chip = ac97->private_data;
641#ifndef CONFIG_SND_ES1968_INPUT
635 unsigned long flags; 642 unsigned long flags;
643#endif
636 644
637 snd_es1968_ac97_wait(chip); 645 snd_es1968_ac97_wait(chip);
638 646
639 /* Write the bus */ 647 /* Write the bus */
648#ifndef CONFIG_SND_ES1968_INPUT
640 spin_lock_irqsave(&chip->ac97_lock, flags); 649 spin_lock_irqsave(&chip->ac97_lock, flags);
650#endif
641 outw(val, chip->io_port + ESM_AC97_DATA); 651 outw(val, chip->io_port + ESM_AC97_DATA);
642 /*msleep(1);*/ 652 /*msleep(1);*/
643 outb(reg, chip->io_port + ESM_AC97_INDEX); 653 outb(reg, chip->io_port + ESM_AC97_INDEX);
644 /*msleep(1);*/ 654 /*msleep(1);*/
655#ifndef CONFIG_SND_ES1968_INPUT
645 spin_unlock_irqrestore(&chip->ac97_lock, flags); 656 spin_unlock_irqrestore(&chip->ac97_lock, flags);
657#endif
646} 658}
647 659
648static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 660static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
649{ 661{
650 u16 data = 0; 662 u16 data = 0;
651 struct es1968 *chip = ac97->private_data; 663 struct es1968 *chip = ac97->private_data;
664#ifndef CONFIG_SND_ES1968_INPUT
652 unsigned long flags; 665 unsigned long flags;
666#endif
653 667
654 snd_es1968_ac97_wait(chip); 668 snd_es1968_ac97_wait(chip);
655 669
670#ifndef CONFIG_SND_ES1968_INPUT
656 spin_lock_irqsave(&chip->ac97_lock, flags); 671 spin_lock_irqsave(&chip->ac97_lock, flags);
672#endif
657 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX); 673 outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
658 /*msleep(1);*/ 674 /*msleep(1);*/
659 675
@@ -661,7 +677,9 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
661 data = inw(chip->io_port + ESM_AC97_DATA); 677 data = inw(chip->io_port + ESM_AC97_DATA);
662 /*msleep(1);*/ 678 /*msleep(1);*/
663 } 679 }
680#ifndef CONFIG_SND_ES1968_INPUT
664 spin_unlock_irqrestore(&chip->ac97_lock, flags); 681 spin_unlock_irqrestore(&chip->ac97_lock, flags);
682#endif
665 683
666 return data; 684 return data;
667} 685}
@@ -1874,13 +1892,17 @@ static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
1874 } 1892 }
1875} 1893}
1876 1894
1877/* 1895/* The hardware volume works by incrementing / decrementing 2 counters
1878 */ 1896 (without wrap around) in response to volume button presses and then
1897 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1898 of a byte wide register. The meaning of bits 0 and 4 is unknown. */
1879static void es1968_update_hw_volume(unsigned long private_data) 1899static void es1968_update_hw_volume(unsigned long private_data)
1880{ 1900{
1881 struct es1968 *chip = (struct es1968 *) private_data; 1901 struct es1968 *chip = (struct es1968 *) private_data;
1882 int x, val; 1902 int x, val;
1903#ifndef CONFIG_SND_ES1968_INPUT
1883 unsigned long flags; 1904 unsigned long flags;
1905#endif
1884 1906
1885 /* Figure out which volume control button was pushed, 1907 /* Figure out which volume control button was pushed,
1886 based on differences from the default register 1908 based on differences from the default register
@@ -1895,6 +1917,7 @@ static void es1968_update_hw_volume(unsigned long private_data)
1895 if (chip->in_suspend) 1917 if (chip->in_suspend)
1896 return; 1918 return;
1897 1919
1920#ifndef CONFIG_SND_ES1968_INPUT
1898 if (! chip->master_switch || ! chip->master_volume) 1921 if (! chip->master_switch || ! chip->master_volume)
1899 return; 1922 return;
1900 1923
@@ -1937,6 +1960,35 @@ static void es1968_update_hw_volume(unsigned long private_data)
1937 break; 1960 break;
1938 } 1961 }
1939 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1962 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1963#else
1964 if (!chip->input_dev)
1965 return;
1966
1967 val = 0;
1968 switch (x) {
1969 case 0x88:
1970 /* The counters have not changed, yet we've received a HV
1971 interrupt. According to tests run by various people this
1972 happens when pressing the mute button. */
1973 val = KEY_MUTE;
1974 break;
1975 case 0xaa:
1976 /* counters increased by 1 -> volume up */
1977 val = KEY_VOLUMEUP;
1978 break;
1979 case 0x66:
1980 /* counters decreased by 1 -> volume down */
1981 val = KEY_VOLUMEDOWN;
1982 break;
1983 }
1984
1985 if (val) {
1986 input_report_key(chip->input_dev, val, 1);
1987 input_sync(chip->input_dev);
1988 input_report_key(chip->input_dev, val, 0);
1989 input_sync(chip->input_dev);
1990 }
1991#endif
1940} 1992}
1941 1993
1942/* 1994/*
@@ -1953,7 +2005,11 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4); 2005 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
1954 2006
1955 if (event & ESM_HWVOL_IRQ) 2007 if (event & ESM_HWVOL_IRQ)
2008#ifdef CONFIG_SND_ES1968_INPUT
2009 es1968_update_hw_volume((unsigned long)chip);
2010#else
1956 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */ 2011 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
2012#endif
1957 2013
1958 /* else ack 'em all, i imagine */ 2014 /* else ack 'em all, i imagine */
1959 outb(0xFF, chip->io_port + 0x1A); 2015 outb(0xFF, chip->io_port + 0x1A);
@@ -1993,7 +2049,9 @@ snd_es1968_mixer(struct es1968 *chip)
1993{ 2049{
1994 struct snd_ac97_bus *pbus; 2050 struct snd_ac97_bus *pbus;
1995 struct snd_ac97_template ac97; 2051 struct snd_ac97_template ac97;
2052#ifndef CONFIG_SND_ES1968_INPUT
1996 struct snd_ctl_elem_id elem_id; 2053 struct snd_ctl_elem_id elem_id;
2054#endif
1997 int err; 2055 int err;
1998 static struct snd_ac97_bus_ops ops = { 2056 static struct snd_ac97_bus_ops ops = {
1999 .write = snd_es1968_ac97_write, 2057 .write = snd_es1968_ac97_write,
@@ -2009,6 +2067,7 @@ snd_es1968_mixer(struct es1968 *chip)
2009 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0) 2067 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
2010 return err; 2068 return err;
2011 2069
2070#ifndef CONFIG_SND_ES1968_INPUT
2012 /* attach master switch / volumes for h/w volume control */ 2071 /* attach master switch / volumes for h/w volume control */
2013 memset(&elem_id, 0, sizeof(elem_id)); 2072 memset(&elem_id, 0, sizeof(elem_id));
2014 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2073 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -2018,6 +2077,7 @@ snd_es1968_mixer(struct es1968 *chip)
2018 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2077 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2019 strcpy(elem_id.name, "Master Playback Volume"); 2078 strcpy(elem_id.name, "Master Playback Volume");
2020 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); 2079 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2080#endif
2021 2081
2022 return 0; 2082 return 0;
2023} 2083}
@@ -2341,6 +2401,7 @@ static void snd_es1968_start_irq(struct es1968 *chip)
2341 w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME; 2401 w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME;
2342 if (chip->rmidi) 2402 if (chip->rmidi)
2343 w |= ESM_HIRQ_MPU401; 2403 w |= ESM_HIRQ_MPU401;
2404 outb(w, chip->io_port + 0x1A);
2344 outw(w, chip->io_port + ESM_PORT_HOST_IRQ); 2405 outw(w, chip->io_port + ESM_PORT_HOST_IRQ);
2345} 2406}
2346 2407
@@ -2474,8 +2535,49 @@ static inline int snd_es1968_create_gameport(struct es1968 *chip, int dev) { ret
2474static inline void snd_es1968_free_gameport(struct es1968 *chip) { } 2535static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
2475#endif 2536#endif
2476 2537
2538#ifdef CONFIG_SND_ES1968_INPUT
2539static int __devinit snd_es1968_input_register(struct es1968 *chip)
2540{
2541 struct input_dev *input_dev;
2542 int err;
2543
2544 input_dev = input_allocate_device();
2545 if (!input_dev)
2546 return -ENOMEM;
2547
2548 snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
2549 pci_name(chip->pci));
2550
2551 input_dev->name = chip->card->driver;
2552 input_dev->phys = chip->phys;
2553 input_dev->id.bustype = BUS_PCI;
2554 input_dev->id.vendor = chip->pci->vendor;
2555 input_dev->id.product = chip->pci->device;
2556 input_dev->dev.parent = &chip->pci->dev;
2557
2558 __set_bit(EV_KEY, input_dev->evbit);
2559 __set_bit(KEY_MUTE, input_dev->keybit);
2560 __set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
2561 __set_bit(KEY_VOLUMEUP, input_dev->keybit);
2562
2563 err = input_register_device(input_dev);
2564 if (err) {
2565 input_free_device(input_dev);
2566 return err;
2567 }
2568
2569 chip->input_dev = input_dev;
2570 return 0;
2571}
2572#endif /* CONFIG_SND_ES1968_INPUT */
2573
2477static int snd_es1968_free(struct es1968 *chip) 2574static int snd_es1968_free(struct es1968 *chip)
2478{ 2575{
2576#ifdef CONFIG_SND_ES1968_INPUT
2577 if (chip->input_dev)
2578 input_unregister_device(chip->input_dev);
2579#endif
2580
2479 if (chip->io_port) { 2581 if (chip->io_port) {
2480 if (chip->irq >= 0) 2582 if (chip->irq >= 0)
2481 synchronize_irq(chip->irq); 2583 synchronize_irq(chip->irq);
@@ -2486,8 +2588,6 @@ static int snd_es1968_free(struct es1968 *chip)
2486 if (chip->irq >= 0) 2588 if (chip->irq >= 0)
2487 free_irq(chip->irq, chip); 2589 free_irq(chip->irq, chip);
2488 snd_es1968_free_gameport(chip); 2590 snd_es1968_free_gameport(chip);
2489 chip->master_switch = NULL;
2490 chip->master_volume = NULL;
2491 pci_release_regions(chip->pci); 2591 pci_release_regions(chip->pci);
2492 pci_disable_device(chip->pci); 2592 pci_disable_device(chip->pci);
2493 kfree(chip); 2593 kfree(chip);
@@ -2558,9 +2658,11 @@ static int __devinit snd_es1968_create(struct snd_card *card,
2558 spin_lock_init(&chip->substream_lock); 2658 spin_lock_init(&chip->substream_lock);
2559 INIT_LIST_HEAD(&chip->buf_list); 2659 INIT_LIST_HEAD(&chip->buf_list);
2560 INIT_LIST_HEAD(&chip->substream_list); 2660 INIT_LIST_HEAD(&chip->substream_list);
2561 spin_lock_init(&chip->ac97_lock);
2562 mutex_init(&chip->memory_mutex); 2661 mutex_init(&chip->memory_mutex);
2662#ifndef CONFIG_SND_ES1968_INPUT
2663 spin_lock_init(&chip->ac97_lock);
2563 tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip); 2664 tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
2665#endif
2564 chip->card = card; 2666 chip->card = card;
2565 chip->pci = pci; 2667 chip->pci = pci;
2566 chip->irq = -1; 2668 chip->irq = -1;
@@ -2713,6 +2815,13 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci,
2713 2815
2714 snd_es1968_create_gameport(chip, dev); 2816 snd_es1968_create_gameport(chip, dev);
2715 2817
2818#ifdef CONFIG_SND_ES1968_INPUT
2819 err = snd_es1968_input_register(chip);
2820 if (err)
2821 snd_printk(KERN_WARNING "Input device registration "
2822 "failed with error %i", err);
2823#endif
2824
2716 snd_es1968_start_irq(chip); 2825 snd_es1968_start_irq(chip);
2717 2826
2718 chip->clock = clock[dev]; 2827 chip->clock = clock[dev];
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 567348b05b5a..9194c3c1d04a 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -145,6 +145,7 @@ config SND_HDA_CODEC_NVHDMI
145 145
146config SND_HDA_CODEC_INTELHDMI 146config SND_HDA_CODEC_INTELHDMI
147 bool "Build INTEL HDMI HD-audio codec support" 147 bool "Build INTEL HDMI HD-audio codec support"
148 select SND_DYNAMIC_MINORS
148 default y 149 default y
149 help 150 help
150 Say Y here to include INTEL HDMI HD-audio codec support in 151 Say Y here to include INTEL HDMI HD-audio codec support in
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0e76ac2b2ace..a3d638c8c1fd 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1209,8 +1209,7 @@ static void free_hda_cache(struct hda_cache_rec *cache)
1209} 1209}
1210 1210
1211/* query the hash. allocate an entry if not found. */ 1211/* query the hash. allocate an entry if not found. */
1212static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache, 1212static struct hda_cache_head *get_hash(struct hda_cache_rec *cache, u32 key)
1213 u32 key)
1214{ 1213{
1215 u16 idx = key % (u16)ARRAY_SIZE(cache->hash); 1214 u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
1216 u16 cur = cache->hash[idx]; 1215 u16 cur = cache->hash[idx];
@@ -1222,17 +1221,27 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
1222 return info; 1221 return info;
1223 cur = info->next; 1222 cur = info->next;
1224 } 1223 }
1224 return NULL;
1225}
1225 1226
1226 /* add a new hash entry */ 1227/* query the hash. allocate an entry if not found. */
1227 info = snd_array_new(&cache->buf); 1228static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
1228 if (!info) 1229 u32 key)
1229 return NULL; 1230{
1230 cur = snd_array_index(&cache->buf, info); 1231 struct hda_cache_head *info = get_hash(cache, key);
1231 info->key = key; 1232 if (!info) {
1232 info->val = 0; 1233 u16 idx, cur;
1233 info->next = cache->hash[idx]; 1234 /* add a new hash entry */
1234 cache->hash[idx] = cur; 1235 info = snd_array_new(&cache->buf);
1235 1236 if (!info)
1237 return NULL;
1238 cur = snd_array_index(&cache->buf, info);
1239 info->key = key;
1240 info->val = 0;
1241 idx = key % (u16)ARRAY_SIZE(cache->hash);
1242 info->next = cache->hash[idx];
1243 cache->hash[idx] = cur;
1244 }
1236 return info; 1245 return info;
1237} 1246}
1238 1247
@@ -1461,6 +1470,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
1461 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); 1470 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
1462 if (!info) 1471 if (!info)
1463 return 0; 1472 return 0;
1473 if (snd_BUG_ON(mask & ~0xff))
1474 mask &= 0xff;
1464 val &= mask; 1475 val &= mask;
1465 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; 1476 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
1466 if (info->vol[ch] == val) 1477 if (info->vol[ch] == val)
@@ -1486,6 +1497,9 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1486 int direction, int idx, int mask, int val) 1497 int direction, int idx, int mask, int val)
1487{ 1498{
1488 int ch, ret = 0; 1499 int ch, ret = 0;
1500
1501 if (snd_BUG_ON(mask & ~0xff))
1502 mask &= 0xff;
1489 for (ch = 0; ch < 2; ch++) 1503 for (ch = 0; ch < 2; ch++)
1490 ret |= snd_hda_codec_amp_update(codec, nid, ch, direction, 1504 ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
1491 idx, mask, val); 1505 idx, mask, val);
@@ -2717,6 +2731,41 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
2717EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); 2731EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
2718 2732
2719/** 2733/**
2734 * snd_hda_codec_update_cache - check cache and write the cmd only when needed
2735 * @codec: the HDA codec
2736 * @nid: NID to send the command
2737 * @direct: direct flag
2738 * @verb: the verb to send
2739 * @parm: the parameter for the verb
2740 *
2741 * This function works like snd_hda_codec_write_cache(), but it doesn't send
2742 * command if the parameter is already identical with the cached value.
2743 * If not, it sends the command and refreshes the cache.
2744 *
2745 * Returns 0 if successful, or a negative error code.
2746 */
2747int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
2748 int direct, unsigned int verb, unsigned int parm)
2749{
2750 struct hda_cache_head *c;
2751 u32 key;
2752
2753 /* parm may contain the verb stuff for get/set amp */
2754 verb = verb | (parm >> 8);
2755 parm &= 0xff;
2756 key = build_cmd_cache_key(nid, verb);
2757 mutex_lock(&codec->bus->cmd_mutex);
2758 c = get_hash(&codec->cmd_cache, key);
2759 if (c && c->val == parm) {
2760 mutex_unlock(&codec->bus->cmd_mutex);
2761 return 0;
2762 }
2763 mutex_unlock(&codec->bus->cmd_mutex);
2764 return snd_hda_codec_write_cache(codec, nid, direct, verb, parm);
2765}
2766EXPORT_SYMBOL_HDA(snd_hda_codec_update_cache);
2767
2768/**
2720 * snd_hda_codec_resume_cache - Resume the all commands from the cache 2769 * snd_hda_codec_resume_cache - Resume the all commands from the cache
2721 * @codec: HD-audio codec 2770 * @codec: HD-audio codec
2722 * 2771 *
@@ -4218,7 +4267,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4218 break; 4267 break;
4219 case AC_JACK_MIC_IN: { 4268 case AC_JACK_MIC_IN: {
4220 int preferred, alt; 4269 int preferred, alt;
4221 if (loc == AC_JACK_LOC_FRONT) { 4270 if (loc == AC_JACK_LOC_FRONT ||
4271 (loc & 0x30) == AC_JACK_LOC_INTERNAL) {
4222 preferred = AUTO_PIN_FRONT_MIC; 4272 preferred = AUTO_PIN_FRONT_MIC;
4223 alt = AUTO_PIN_MIC; 4273 alt = AUTO_PIN_MIC;
4224 } else { 4274 } else {
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index b75da47571e6..49e939e7e5cd 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -885,9 +885,12 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
885 int direct, unsigned int verb, unsigned int parm); 885 int direct, unsigned int verb, unsigned int parm);
886void snd_hda_sequence_write_cache(struct hda_codec *codec, 886void snd_hda_sequence_write_cache(struct hda_codec *codec,
887 const struct hda_verb *seq); 887 const struct hda_verb *seq);
888int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
889 int direct, unsigned int verb, unsigned int parm);
888void snd_hda_codec_resume_cache(struct hda_codec *codec); 890void snd_hda_codec_resume_cache(struct hda_codec *codec);
889#else 891#else
890#define snd_hda_codec_write_cache snd_hda_codec_write 892#define snd_hda_codec_write_cache snd_hda_codec_write
893#define snd_hda_codec_update_cache snd_hda_codec_write
891#define snd_hda_sequence_write_cache snd_hda_sequence_write 894#define snd_hda_sequence_write_cache snd_hda_sequence_write
892#endif 895#endif
893 896
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index cec68152dcb1..170610e1d7da 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -84,7 +84,7 @@ module_param_array(bdl_pos_adj, int, NULL, 0644);
84MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 84MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
85module_param_array(probe_mask, int, NULL, 0444); 85module_param_array(probe_mask, int, NULL, 0444);
86MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); 86MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
87module_param_array(probe_only, bool, NULL, 0444); 87module_param_array(probe_only, int, NULL, 0444);
88MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization."); 88MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
89module_param(single_cmd, bool, 0444); 89module_param(single_cmd, bool, 0444);
90MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " 90MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
@@ -174,7 +174,7 @@ MODULE_DESCRIPTION("Intel HDA driver");
174#define ICH6_GSTS_FSTS (1 << 1) /* flush status */ 174#define ICH6_GSTS_FSTS (1 << 1) /* flush status */
175#define ICH6_REG_INTCTL 0x20 175#define ICH6_REG_INTCTL 0x20
176#define ICH6_REG_INTSTS 0x24 176#define ICH6_REG_INTSTS 0x24
177#define ICH6_REG_WALCLK 0x30 177#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */
178#define ICH6_REG_SYNC 0x34 178#define ICH6_REG_SYNC 0x34
179#define ICH6_REG_CORBLBASE 0x40 179#define ICH6_REG_CORBLBASE 0x40
180#define ICH6_REG_CORBUBASE 0x44 180#define ICH6_REG_CORBUBASE 0x44
@@ -340,8 +340,8 @@ struct azx_dev {
340 unsigned int period_bytes; /* size of the period in bytes */ 340 unsigned int period_bytes; /* size of the period in bytes */
341 unsigned int frags; /* number for period in the play buffer */ 341 unsigned int frags; /* number for period in the play buffer */
342 unsigned int fifo_size; /* FIFO size */ 342 unsigned int fifo_size; /* FIFO size */
343 unsigned long start_jiffies; /* start + minimum jiffies */ 343 unsigned long start_wallclk; /* start + minimum wallclk */
344 unsigned long min_jiffies; /* minimum jiffies before position is valid */ 344 unsigned long period_wallclk; /* wallclk for period */
345 345
346 void __iomem *sd_addr; /* stream descriptor pointer */ 346 void __iomem *sd_addr; /* stream descriptor pointer */
347 347
@@ -361,7 +361,6 @@ struct azx_dev {
361 unsigned int opened :1; 361 unsigned int opened :1;
362 unsigned int running :1; 362 unsigned int running :1;
363 unsigned int irq_pending :1; 363 unsigned int irq_pending :1;
364 unsigned int start_flag: 1; /* stream full start flag */
365 /* 364 /*
366 * For VIA: 365 * For VIA:
367 * A flag to ensure DMA position is 0 366 * A flag to ensure DMA position is 0
@@ -425,7 +424,7 @@ struct azx {
425 struct snd_dma_buffer posbuf; 424 struct snd_dma_buffer posbuf;
426 425
427 /* flags */ 426 /* flags */
428 int position_fix; 427 int position_fix[2]; /* for both playback/capture streams */
429 int poll_count; 428 int poll_count;
430 unsigned int running :1; 429 unsigned int running :1;
431 unsigned int initialized :1; 430 unsigned int initialized :1;
@@ -858,10 +857,13 @@ static void azx_power_notify(struct hda_bus *bus);
858#endif 857#endif
859 858
860/* reset codec link */ 859/* reset codec link */
861static int azx_reset(struct azx *chip) 860static int azx_reset(struct azx *chip, int full_reset)
862{ 861{
863 int count; 862 int count;
864 863
864 if (!full_reset)
865 goto __skip;
866
865 /* clear STATESTS */ 867 /* clear STATESTS */
866 azx_writeb(chip, STATESTS, STATESTS_INT_MASK); 868 azx_writeb(chip, STATESTS, STATESTS_INT_MASK);
867 869
@@ -887,6 +889,7 @@ static int azx_reset(struct azx *chip)
887 /* Brent Chartrand said to wait >= 540us for codecs to initialize */ 889 /* Brent Chartrand said to wait >= 540us for codecs to initialize */
888 msleep(1); 890 msleep(1);
889 891
892 __skip:
890 /* check to see if controller is ready */ 893 /* check to see if controller is ready */
891 if (!azx_readb(chip, GCTL)) { 894 if (!azx_readb(chip, GCTL)) {
892 snd_printd(SFX "azx_reset: controller not ready!\n"); 895 snd_printd(SFX "azx_reset: controller not ready!\n");
@@ -998,13 +1001,13 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
998/* 1001/*
999 * reset and start the controller registers 1002 * reset and start the controller registers
1000 */ 1003 */
1001static void azx_init_chip(struct azx *chip) 1004static void azx_init_chip(struct azx *chip, int full_reset)
1002{ 1005{
1003 if (chip->initialized) 1006 if (chip->initialized)
1004 return; 1007 return;
1005 1008
1006 /* reset controller */ 1009 /* reset controller */
1007 azx_reset(chip); 1010 azx_reset(chip, full_reset);
1008 1011
1009 /* initialize interrupts */ 1012 /* initialize interrupts */
1010 azx_int_clear(chip); 1013 azx_int_clear(chip);
@@ -1302,8 +1305,10 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1302 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr)); 1305 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
1303 1306
1304 /* enable the position buffer */ 1307 /* enable the position buffer */
1305 if (chip->position_fix == POS_FIX_POSBUF || 1308 if (chip->position_fix[0] == POS_FIX_POSBUF ||
1306 chip->position_fix == POS_FIX_AUTO || 1309 chip->position_fix[0] == POS_FIX_AUTO ||
1310 chip->position_fix[1] == POS_FIX_POSBUF ||
1311 chip->position_fix[1] == POS_FIX_AUTO ||
1307 chip->via_dmapos_patch) { 1312 chip->via_dmapos_patch) {
1308 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) 1313 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
1309 azx_writel(chip, DPLBASE, 1314 azx_writel(chip, DPLBASE,
@@ -1348,7 +1353,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1348 1353
1349 bus->in_reset = 1; 1354 bus->in_reset = 1;
1350 azx_stop_chip(chip); 1355 azx_stop_chip(chip);
1351 azx_init_chip(chip); 1356 azx_init_chip(chip, 1);
1352#ifdef CONFIG_PM 1357#ifdef CONFIG_PM
1353 if (chip->initialized) { 1358 if (chip->initialized) {
1354 int i; 1359 int i;
@@ -1422,7 +1427,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1422 * get back to the sanity state. 1427 * get back to the sanity state.
1423 */ 1428 */
1424 azx_stop_chip(chip); 1429 azx_stop_chip(chip);
1425 azx_init_chip(chip); 1430 azx_init_chip(chip, 1);
1426 } 1431 }
1427 } 1432 }
1428 } 1433 }
@@ -1670,8 +1675,9 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1670 return err; 1675 return err;
1671 } 1676 }
1672 1677
1673 azx_dev->min_jiffies = (runtime->period_size * HZ) / 1678 /* wallclk has 24Mhz clock source */
1674 (runtime->rate * 2); 1679 azx_dev->period_wallclk = (((runtime->period_size * 24000) /
1680 runtime->rate) * 1000);
1675 azx_setup_controller(chip, azx_dev); 1681 azx_setup_controller(chip, azx_dev);
1676 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1682 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1677 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; 1683 azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
@@ -1725,14 +1731,15 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1725 if (s->pcm->card != substream->pcm->card) 1731 if (s->pcm->card != substream->pcm->card)
1726 continue; 1732 continue;
1727 azx_dev = get_azx_dev(s); 1733 azx_dev = get_azx_dev(s);
1728 if (rstart) { 1734 if (start) {
1729 azx_dev->start_flag = 1; 1735 azx_dev->start_wallclk = azx_readl(chip, WALLCLK);
1730 azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies; 1736 if (!rstart)
1731 } 1737 azx_dev->start_wallclk -=
1732 if (start) 1738 azx_dev->period_wallclk;
1733 azx_stream_start(chip, azx_dev); 1739 azx_stream_start(chip, azx_dev);
1734 else 1740 } else {
1735 azx_stream_stop(chip, azx_dev); 1741 azx_stream_stop(chip, azx_dev);
1742 }
1736 azx_dev->running = start; 1743 azx_dev->running = start;
1737 } 1744 }
1738 spin_unlock(&chip->reg_lock); 1745 spin_unlock(&chip->reg_lock);
@@ -1843,13 +1850,16 @@ static unsigned int azx_get_position(struct azx *chip,
1843 1850
1844 if (chip->via_dmapos_patch) 1851 if (chip->via_dmapos_patch)
1845 pos = azx_via_get_position(chip, azx_dev); 1852 pos = azx_via_get_position(chip, azx_dev);
1846 else if (chip->position_fix == POS_FIX_POSBUF || 1853 else {
1847 chip->position_fix == POS_FIX_AUTO) { 1854 int stream = azx_dev->substream->stream;
1848 /* use the position buffer */ 1855 if (chip->position_fix[stream] == POS_FIX_POSBUF ||
1849 pos = le32_to_cpu(*azx_dev->posbuf); 1856 chip->position_fix[stream] == POS_FIX_AUTO) {
1850 } else { 1857 /* use the position buffer */
1851 /* read LPIB */ 1858 pos = le32_to_cpu(*azx_dev->posbuf);
1852 pos = azx_sd_readl(azx_dev, SD_LPIB); 1859 } else {
1860 /* read LPIB */
1861 pos = azx_sd_readl(azx_dev, SD_LPIB);
1862 }
1853 } 1863 }
1854 if (pos >= azx_dev->bufsize) 1864 if (pos >= azx_dev->bufsize)
1855 pos = 0; 1865 pos = 0;
@@ -1876,32 +1886,35 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
1876 */ 1886 */
1877static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) 1887static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1878{ 1888{
1889 u32 wallclk;
1879 unsigned int pos; 1890 unsigned int pos;
1891 int stream;
1880 1892
1881 if (azx_dev->start_flag && 1893 wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
1882 time_before_eq(jiffies, azx_dev->start_jiffies)) 1894 if (wallclk < (azx_dev->period_wallclk * 2) / 3)
1883 return -1; /* bogus (too early) interrupt */ 1895 return -1; /* bogus (too early) interrupt */
1884 azx_dev->start_flag = 0;
1885 1896
1897 stream = azx_dev->substream->stream;
1886 pos = azx_get_position(chip, azx_dev); 1898 pos = azx_get_position(chip, azx_dev);
1887 if (chip->position_fix == POS_FIX_AUTO) { 1899 if (chip->position_fix[stream] == POS_FIX_AUTO) {
1888 if (!pos) { 1900 if (!pos) {
1889 printk(KERN_WARNING 1901 printk(KERN_WARNING
1890 "hda-intel: Invalid position buffer, " 1902 "hda-intel: Invalid position buffer, "
1891 "using LPIB read method instead.\n"); 1903 "using LPIB read method instead.\n");
1892 chip->position_fix = POS_FIX_LPIB; 1904 chip->position_fix[stream] = POS_FIX_LPIB;
1893 pos = azx_get_position(chip, azx_dev); 1905 pos = azx_get_position(chip, azx_dev);
1894 } else 1906 } else
1895 chip->position_fix = POS_FIX_POSBUF; 1907 chip->position_fix[stream] = POS_FIX_POSBUF;
1896 } 1908 }
1897 1909
1898 if (!bdl_pos_adj[chip->dev_index])
1899 return 1; /* no delayed ack */
1900 if (WARN_ONCE(!azx_dev->period_bytes, 1910 if (WARN_ONCE(!azx_dev->period_bytes,
1901 "hda-intel: zero azx_dev->period_bytes")) 1911 "hda-intel: zero azx_dev->period_bytes"))
1902 return 0; /* this shouldn't happen! */ 1912 return -1; /* this shouldn't happen! */
1903 if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) 1913 if (wallclk <= azx_dev->period_wallclk &&
1904 return 0; /* NG - it's below the period boundary */ 1914 pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
1915 /* NG - it's below the first next period boundary */
1916 return bdl_pos_adj[chip->dev_index] ? 0 : -1;
1917 azx_dev->start_wallclk = wallclk;
1905 return 1; /* OK, it's fine */ 1918 return 1; /* OK, it's fine */
1906} 1919}
1907 1920
@@ -1911,7 +1924,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1911static void azx_irq_pending_work(struct work_struct *work) 1924static void azx_irq_pending_work(struct work_struct *work)
1912{ 1925{
1913 struct azx *chip = container_of(work, struct azx, irq_pending_work); 1926 struct azx *chip = container_of(work, struct azx, irq_pending_work);
1914 int i, pending; 1927 int i, pending, ok;
1915 1928
1916 if (!chip->irq_pending_warned) { 1929 if (!chip->irq_pending_warned) {
1917 printk(KERN_WARNING 1930 printk(KERN_WARNING
@@ -1930,11 +1943,14 @@ static void azx_irq_pending_work(struct work_struct *work)
1930 !azx_dev->substream || 1943 !azx_dev->substream ||
1931 !azx_dev->running) 1944 !azx_dev->running)
1932 continue; 1945 continue;
1933 if (azx_position_ok(chip, azx_dev)) { 1946 ok = azx_position_ok(chip, azx_dev);
1947 if (ok > 0) {
1934 azx_dev->irq_pending = 0; 1948 azx_dev->irq_pending = 0;
1935 spin_unlock(&chip->reg_lock); 1949 spin_unlock(&chip->reg_lock);
1936 snd_pcm_period_elapsed(azx_dev->substream); 1950 snd_pcm_period_elapsed(azx_dev->substream);
1937 spin_lock(&chip->reg_lock); 1951 spin_lock(&chip->reg_lock);
1952 } else if (ok < 0) {
1953 pending = 0; /* too early */
1938 } else 1954 } else
1939 pending++; 1955 pending++;
1940 } 1956 }
@@ -2112,7 +2128,7 @@ static void azx_power_notify(struct hda_bus *bus)
2112 } 2128 }
2113 } 2129 }
2114 if (power_on) 2130 if (power_on)
2115 azx_init_chip(chip); 2131 azx_init_chip(chip, 1);
2116 else if (chip->running && power_save_controller && 2132 else if (chip->running && power_save_controller &&
2117 !bus->power_keep_link_on) 2133 !bus->power_keep_link_on)
2118 azx_stop_chip(chip); 2134 azx_stop_chip(chip);
@@ -2182,7 +2198,7 @@ static int azx_resume(struct pci_dev *pci)
2182 azx_init_pci(chip); 2198 azx_init_pci(chip);
2183 2199
2184 if (snd_hda_codecs_inuse(chip->bus)) 2200 if (snd_hda_codecs_inuse(chip->bus))
2185 azx_init_chip(chip); 2201 azx_init_chip(chip, 1);
2186 2202
2187 snd_hda_resume(chip->bus); 2203 snd_hda_resume(chip->bus);
2188 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2204 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2431,7 +2447,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2431 chip->dev_index = dev; 2447 chip->dev_index = dev;
2432 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); 2448 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
2433 2449
2434 chip->position_fix = check_position_fix(chip, position_fix[dev]); 2450 chip->position_fix[0] = chip->position_fix[1] =
2451 check_position_fix(chip, position_fix[dev]);
2435 check_probe_mask(chip, dev); 2452 check_probe_mask(chip, dev);
2436 2453
2437 chip->single_cmd = single_cmd; 2454 chip->single_cmd = single_cmd;
@@ -2577,7 +2594,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2577 2594
2578 /* initialize chip */ 2595 /* initialize chip */
2579 azx_init_pci(chip); 2596 azx_init_pci(chip);
2580 azx_init_chip(chip); 2597 azx_init_chip(chip, (probe_only[dev] & 2) == 0);
2581 2598
2582 /* codec detection */ 2599 /* codec detection */
2583 if (!chip->codec_mask) { 2600 if (!chip->codec_mask) {
@@ -2666,7 +2683,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
2666 goto out_free; 2683 goto out_free;
2667 } 2684 }
2668#endif 2685#endif
2669 if (!probe_only[dev]) { 2686 if ((probe_only[dev] & 1) == 0) {
2670 err = azx_codec_configure(chip); 2687 err = azx_codec_configure(chip);
2671 if (err < 0) 2688 if (err < 0)
2672 goto out_free; 2689 goto out_free;
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 7cee364976ff..7a97f126f6f7 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -361,7 +361,7 @@ struct hda_bus_unsolicited {
361}; 361};
362 362
363/* 363/*
364 * Helper for automatic ping configuration 364 * Helper for automatic pin configuration
365 */ 365 */
366 366
367enum { 367enum {
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index e9fdfc4b1c57..afbe314a5bf3 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -71,9 +71,10 @@ struct ad198x_spec {
71 struct hda_input_mux private_imux; 71 struct hda_input_mux private_imux;
72 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 72 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
73 73
74 unsigned int jack_present :1; 74 unsigned int jack_present: 1;
75 unsigned int inv_jack_detect:1; /* inverted jack-detection */ 75 unsigned int inv_jack_detect: 1;/* inverted jack-detection */
76 unsigned int inv_eapd:1; /* inverted EAPD implementation */ 76 unsigned int inv_eapd: 1; /* inverted EAPD implementation */
77 unsigned int analog_beep: 1; /* analog beep input present */
77 78
78#ifdef CONFIG_SND_HDA_POWER_SAVE 79#ifdef CONFIG_SND_HDA_POWER_SAVE
79 struct hda_loopback_check loopback; 80 struct hda_loopback_check loopback;
@@ -165,6 +166,12 @@ static struct snd_kcontrol_new ad_beep_mixer[] = {
165 { } /* end */ 166 { } /* end */
166}; 167};
167 168
169static struct snd_kcontrol_new ad_beep2_mixer[] = {
170 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
171 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
172 { } /* end */
173};
174
168#define set_beep_amp(spec, nid, idx, dir) \ 175#define set_beep_amp(spec, nid, idx, dir) \
169 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ 176 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
170#else 177#else
@@ -203,7 +210,8 @@ static int ad198x_build_controls(struct hda_codec *codec)
203#ifdef CONFIG_SND_HDA_INPUT_BEEP 210#ifdef CONFIG_SND_HDA_INPUT_BEEP
204 if (spec->beep_amp) { 211 if (spec->beep_amp) {
205 struct snd_kcontrol_new *knew; 212 struct snd_kcontrol_new *knew;
206 for (knew = ad_beep_mixer; knew->name; knew++) { 213 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
214 for ( ; knew->name; knew++) {
207 struct snd_kcontrol *kctl; 215 struct snd_kcontrol *kctl;
208 kctl = snd_ctl_new1(knew, codec); 216 kctl = snd_ctl_new1(knew, codec);
209 if (!kctl) 217 if (!kctl)
@@ -3481,6 +3489,8 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3481 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3489 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3482 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 3490 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3483 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3491 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3492 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3493 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3484 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3494 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3485 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3495 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3486 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 3496 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT),
@@ -3522,6 +3532,8 @@ static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3522 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3532 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3523 /* docking mic boost */ 3533 /* docking mic boost */
3524 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3534 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3535 /* Analog PC Beeper - allow firmware/ACPI beeps */
3536 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3525 /* Analog mixer - docking mic; mute as default */ 3537 /* Analog mixer - docking mic; mute as default */
3526 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3538 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3527 /* enable EAPD bit */ 3539 /* enable EAPD bit */
@@ -3654,6 +3666,7 @@ static int patch_ad1984(struct hda_codec *codec)
3654 spec->input_mux = &ad1984_thinkpad_capture_source; 3666 spec->input_mux = &ad1984_thinkpad_capture_source;
3655 spec->mixers[0] = ad1984_thinkpad_mixers; 3667 spec->mixers[0] = ad1984_thinkpad_mixers;
3656 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; 3668 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3669 spec->analog_beep = 1;
3657 break; 3670 break;
3658 case AD1984_DELL_DESKTOP: 3671 case AD1984_DELL_DESKTOP:
3659 spec->multiout.dig_out_nid = 0; 3672 spec->multiout.dig_out_nid = 0;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index feabb44c7ca4..e863649d31f5 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -115,6 +115,7 @@ struct conexant_spec {
115 unsigned int port_d_mode; 115 unsigned int port_d_mode;
116 unsigned int dell_vostro:1; 116 unsigned int dell_vostro:1;
117 unsigned int ideapad:1; 117 unsigned int ideapad:1;
118 unsigned int thinkpad:1;
118 119
119 unsigned int ext_mic_present; 120 unsigned int ext_mic_present;
120 unsigned int recording; 121 unsigned int recording;
@@ -1784,6 +1785,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1784 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1785 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1786 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1786 /* SPDIF route: PCM */ 1787 /* SPDIF route: PCM */
1788 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1787 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1789 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1788 /* EAPD */ 1790 /* EAPD */
1789 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1791 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -1840,6 +1842,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1840 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1841 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1842 /* SPDIF route: PCM */ 1844 /* SPDIF route: PCM */
1845 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */
1843 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1846 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1844 /* EAPD */ 1847 /* EAPD */
1845 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1848 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -1911,7 +1914,7 @@ enum {
1911 CXT5051_LAPTOP, /* Laptops w/ EAPD support */ 1914 CXT5051_LAPTOP, /* Laptops w/ EAPD support */
1912 CXT5051_HP, /* no docking */ 1915 CXT5051_HP, /* no docking */
1913 CXT5051_HP_DV6736, /* HP without mic switch */ 1916 CXT5051_HP_DV6736, /* HP without mic switch */
1914 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ 1917 CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */
1915 CXT5051_F700, /* HP Compaq Presario F700 */ 1918 CXT5051_F700, /* HP Compaq Presario F700 */
1916 CXT5051_TOSHIBA, /* Toshiba M300 & co */ 1919 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1917 CXT5051_MODELS 1920 CXT5051_MODELS
@@ -2033,6 +2036,9 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
2033 /* Port D (HP/LO) */ 2036 /* Port D (HP/LO) */
2034 pinctl = ((spec->hp_present & 2) && spec->cur_eapd) 2037 pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
2035 ? spec->port_d_mode : 0; 2038 ? spec->port_d_mode : 0;
2039 /* Mute if Port A is connected on Thinkpad */
2040 if (spec->thinkpad && (spec->hp_present & 1))
2041 pinctl = 0;
2036 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2042 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2037 pinctl); 2043 pinctl);
2038 2044
@@ -2213,6 +2219,50 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec)
2213 } 2219 }
2214} 2220}
2215 2221
2222/* toggle input of built-in digital mic and mic jack appropriately
2223 order is: external mic -> dock mic -> interal mic */
2224static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2225{
2226 unsigned int ext_present, dock_present;
2227
2228 static struct hda_verb ext_mic_present[] = {
2229 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2230 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2231 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2232 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2233 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2234 {}
2235 };
2236 static struct hda_verb dock_mic_present[] = {
2237 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2238 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2239 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2240 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2241 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2242 {}
2243 };
2244 static struct hda_verb ext_mic_absent[] = {
2245 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2246 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2247 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2248 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2249 {}
2250 };
2251
2252 ext_present = snd_hda_jack_detect(codec, 0x1b);
2253 dock_present = snd_hda_jack_detect(codec, 0x1a);
2254 if (ext_present) {
2255 snd_printdd("CXT5066: external microphone detected\n");
2256 snd_hda_sequence_write(codec, ext_mic_present);
2257 } else if (dock_present) {
2258 snd_printdd("CXT5066: dock microphone detected\n");
2259 snd_hda_sequence_write(codec, dock_mic_present);
2260 } else {
2261 snd_printdd("CXT5066: external microphone absent\n");
2262 snd_hda_sequence_write(codec, ext_mic_absent);
2263 }
2264}
2265
2216/* mute internal speaker if HP is plugged */ 2266/* mute internal speaker if HP is plugged */
2217static void cxt5066_hp_automute(struct hda_codec *codec) 2267static void cxt5066_hp_automute(struct hda_codec *codec)
2218{ 2268{
@@ -2225,7 +2275,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2225 /* Port D */ 2275 /* Port D */
2226 portD = snd_hda_jack_detect(codec, 0x1c); 2276 portD = snd_hda_jack_detect(codec, 0x1c);
2227 2277
2228 spec->hp_present = !!(portA | portD); 2278 spec->hp_present = !!(portA);
2279 spec->hp_present |= portD ? 2 : 0;
2229 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", 2280 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2230 portA, portD, spec->hp_present); 2281 portA, portD, spec->hp_present);
2231 cxt5066_update_speaker(codec); 2282 cxt5066_update_speaker(codec);
@@ -2276,6 +2327,20 @@ static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2276 } 2327 }
2277} 2328}
2278 2329
2330/* unsolicited event for jack sensing */
2331static void cxt5066_thinkpad_event(struct hda_codec *codec, unsigned int res)
2332{
2333 snd_printdd("CXT5066_thinkpad: unsol event %x (%x)\n", res, res >> 26);
2334 switch (res >> 26) {
2335 case CONEXANT_HP_EVENT:
2336 cxt5066_hp_automute(codec);
2337 break;
2338 case CONEXANT_MIC_EVENT:
2339 cxt5066_thinkpad_automic(codec);
2340 break;
2341 }
2342}
2343
2279static const struct hda_input_mux cxt5066_analog_mic_boost = { 2344static const struct hda_input_mux cxt5066_analog_mic_boost = {
2280 .num_items = 5, 2345 .num_items = 5,
2281 .items = { 2346 .items = {
@@ -2294,7 +2359,7 @@ static void cxt5066_set_mic_boost(struct hda_codec *codec)
2294 AC_VERB_SET_AMP_GAIN_MUTE, 2359 AC_VERB_SET_AMP_GAIN_MUTE,
2295 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | 2360 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2296 cxt5066_analog_mic_boost.items[spec->mic_boost].index); 2361 cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2297 if (spec->ideapad) { 2362 if (spec->ideapad || spec->thinkpad) {
2298 /* adjust the internal mic as well...it is not through 0x17 */ 2363 /* adjust the internal mic as well...it is not through 0x17 */
2299 snd_hda_codec_write_cache(codec, 0x23, 0, 2364 snd_hda_codec_write_cache(codec, 0x23, 0,
2300 AC_VERB_SET_AMP_GAIN_MUTE, 2365 AC_VERB_SET_AMP_GAIN_MUTE,
@@ -2782,6 +2847,64 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2782 { } /* end */ 2847 { } /* end */
2783}; 2848};
2784 2849
2850static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2851 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2852 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2853
2854 /* Port G: internal speakers */
2855 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2856 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2857
2858 /* Port A: HP, Amp */
2859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2860 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2861
2862 /* Port B: Mic Dock */
2863 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2864
2865 /* Port C: Mic */
2866 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2867
2868 /* Port D: HP Dock, Amp */
2869 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2870 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2871
2872 /* DAC1 */
2873 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2874
2875 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2876 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2877 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2879 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2880 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2881 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
2882
2883 /* Audio input selector */
2884 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2885 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
2886
2887 /* SPDIF route: PCM */
2888 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2889 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2890
2891 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2892 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2893
2894 /* internal microphone */
2895 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
2896
2897 /* EAPD */
2898 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2899
2900 /* enable unsolicited events for Port A, B, C and D */
2901 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2902 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2903 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2904 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2905 { } /* end */
2906};
2907
2785static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 2908static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2786 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2909 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2787 { } /* end */ 2910 { } /* end */
@@ -2800,6 +2923,8 @@ static int cxt5066_init(struct hda_codec *codec)
2800 cxt5066_vostro_automic(codec); 2923 cxt5066_vostro_automic(codec);
2801 else if (spec->ideapad) 2924 else if (spec->ideapad)
2802 cxt5066_ideapad_automic(codec); 2925 cxt5066_ideapad_automic(codec);
2926 else if (spec->thinkpad)
2927 cxt5066_thinkpad_automic(codec);
2803 } 2928 }
2804 cxt5066_set_mic_boost(codec); 2929 cxt5066_set_mic_boost(codec);
2805 return 0; 2930 return 0;
@@ -2821,20 +2946,22 @@ static int cxt5066_olpc_init(struct hda_codec *codec)
2821} 2946}
2822 2947
2823enum { 2948enum {
2824 CXT5066_LAPTOP, /* Laptops w/ EAPD support */ 2949 CXT5066_LAPTOP, /* Laptops w/ EAPD support */
2825 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 2950 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2826 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 2951 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2827 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ 2952 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */
2828 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */ 2953 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
2954 CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */
2829 CXT5066_MODELS 2955 CXT5066_MODELS
2830}; 2956};
2831 2957
2832static const char *cxt5066_models[CXT5066_MODELS] = { 2958static const char *cxt5066_models[CXT5066_MODELS] = {
2833 [CXT5066_LAPTOP] = "laptop", 2959 [CXT5066_LAPTOP] = "laptop",
2834 [CXT5066_DELL_LAPTOP] = "dell-laptop", 2960 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2835 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 2961 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2836 [CXT5066_DELL_VOSTO] = "dell-vostro", 2962 [CXT5066_DELL_VOSTO] = "dell-vostro",
2837 [CXT5066_IDEAPAD] = "ideapad", 2963 [CXT5066_IDEAPAD] = "ideapad",
2964 [CXT5066_THINKPAD] = "thinkpad",
2838}; 2965};
2839 2966
2840static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 2967static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
@@ -2849,6 +2976,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2849 SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), 2976 SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
2850 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), 2977 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
2851 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), 2978 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
2979 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
2852 {} 2980 {}
2853}; 2981};
2854 2982
@@ -2956,6 +3084,22 @@ static int patch_cxt5066(struct hda_codec *codec)
2956 /* input source automatically selected */ 3084 /* input source automatically selected */
2957 spec->input_mux = NULL; 3085 spec->input_mux = NULL;
2958 break; 3086 break;
3087 case CXT5066_THINKPAD:
3088 codec->patch_ops.init = cxt5066_init;
3089 codec->patch_ops.unsol_event = cxt5066_thinkpad_event;
3090 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3091 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3092 spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
3093 spec->thinkpad = 1;
3094 spec->port_d_mode = PIN_OUT;
3095 spec->mic_boost = 2; /* default 20dB gain */
3096
3097 /* no S/PDIF out */
3098 spec->multiout.dig_out_nid = 0;
3099
3100 /* input source automatically selected */
3101 spec->input_mux = NULL;
3102 break;
2959 } 3103 }
2960 3104
2961 return 0; 3105 return 0;
@@ -2975,6 +3119,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
2975 .patch = patch_cxt5066 }, 3119 .patch = patch_cxt5066 },
2976 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)", 3120 { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
2977 .patch = patch_cxt5066 }, 3121 .patch = patch_cxt5066 },
3122 { .id = 0x14f15069, .name = "CX20585",
3123 .patch = patch_cxt5066 },
2978 {} /* terminator */ 3124 {} /* terminator */
2979}; 3125};
2980 3126
@@ -2983,6 +3129,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15047");
2983MODULE_ALIAS("snd-hda-codec-id:14f15051"); 3129MODULE_ALIAS("snd-hda-codec-id:14f15051");
2984MODULE_ALIAS("snd-hda-codec-id:14f15066"); 3130MODULE_ALIAS("snd-hda-codec-id:14f15066");
2985MODULE_ALIAS("snd-hda-codec-id:14f15067"); 3131MODULE_ALIAS("snd-hda-codec-id:14f15067");
3132MODULE_ALIAS("snd-hda-codec-id:14f15069");
2986 3133
2987MODULE_LICENSE("GPL"); 3134MODULE_LICENSE("GPL");
2988MODULE_DESCRIPTION("Conexant HD-audio codec"); 3135MODULE_DESCRIPTION("Conexant HD-audio codec");
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 2c2bafbf0258..86067ee78632 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -766,7 +766,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
766 if (spec->num_pins >= MAX_HDMI_PINS) { 766 if (spec->num_pins >= MAX_HDMI_PINS) {
767 snd_printk(KERN_WARNING 767 snd_printk(KERN_WARNING
768 "HDMI: no space for pin %d\n", pin_nid); 768 "HDMI: no space for pin %d\n", pin_nid);
769 return -EINVAL; 769 return -E2BIG;
770 } 770 }
771 771
772 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); 772 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
@@ -788,7 +788,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
788 if (spec->num_cvts >= MAX_HDMI_CVTS) { 788 if (spec->num_cvts >= MAX_HDMI_CVTS) {
789 snd_printk(KERN_WARNING 789 snd_printk(KERN_WARNING
790 "HDMI: no space for converter %d\n", nid); 790 "HDMI: no space for converter %d\n", nid);
791 return -EINVAL; 791 return -E2BIG;
792 } 792 }
793 793
794 spec->cvt[spec->num_cvts] = nid; 794 spec->cvt[spec->num_cvts] = nid;
@@ -820,15 +820,13 @@ static int hdmi_parse_codec(struct hda_codec *codec)
820 820
821 switch (type) { 821 switch (type) {
822 case AC_WID_AUD_OUT: 822 case AC_WID_AUD_OUT:
823 if (hdmi_add_cvt(codec, nid) < 0) 823 hdmi_add_cvt(codec, nid);
824 return -EINVAL;
825 break; 824 break;
826 case AC_WID_PIN: 825 case AC_WID_PIN:
827 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 826 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
828 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) 827 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
829 continue; 828 continue;
830 if (hdmi_add_pin(codec, nid) < 0) 829 hdmi_add_pin(codec, nid);
831 return -EINVAL;
832 break; 830 break;
833 } 831 }
834 } 832 }
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 88d035104cc5..b81d23e42ace 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -40,7 +40,7 @@
40 * 40 *
41 * The HDA correspondence of pipes/ports are converter/pin nodes. 41 * The HDA correspondence of pipes/ports are converter/pin nodes.
42 */ 42 */
43#define MAX_HDMI_CVTS 2 43#define MAX_HDMI_CVTS 3
44#define MAX_HDMI_PINS 3 44#define MAX_HDMI_PINS 3
45 45
46#include "patch_hdmi.c" 46#include "patch_hdmi.c"
@@ -48,6 +48,7 @@
48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = { 48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
49 "INTEL HDMI 0", 49 "INTEL HDMI 0",
50 "INTEL HDMI 1", 50 "INTEL HDMI 1",
51 "INTEL HDMI 2",
51}; 52};
52 53
53/* 54/*
@@ -185,14 +186,15 @@ static int patch_intel_hdmi(struct hda_codec *codec)
185} 186}
186 187
187static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { 188static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
188 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, 189{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_intel_hdmi },
189 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, 190{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_intel_hdmi },
190 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, 191{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_intel_hdmi },
191 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, 192{ .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_intel_hdmi },
192 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, 193{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_intel_hdmi },
193 { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi }, 194{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_intel_hdmi },
194 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, 195{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_intel_hdmi },
195 {} /* terminator */ 196{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
197{} /* terminator */
196}; 198};
197 199
198MODULE_ALIAS("snd-hda-codec-id:808629fb"); 200MODULE_ALIAS("snd-hda-codec-id:808629fb");
@@ -200,6 +202,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862801");
200MODULE_ALIAS("snd-hda-codec-id:80862802"); 202MODULE_ALIAS("snd-hda-codec-id:80862802");
201MODULE_ALIAS("snd-hda-codec-id:80862803"); 203MODULE_ALIAS("snd-hda-codec-id:80862803");
202MODULE_ALIAS("snd-hda-codec-id:80862804"); 204MODULE_ALIAS("snd-hda-codec-id:80862804");
205MODULE_ALIAS("snd-hda-codec-id:80862805");
203MODULE_ALIAS("snd-hda-codec-id:80860054"); 206MODULE_ALIAS("snd-hda-codec-id:80860054");
204MODULE_ALIAS("snd-hda-codec-id:10951392"); 207MODULE_ALIAS("snd-hda-codec-id:10951392");
205 208
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 886d8e46bb37..53538b0f9991 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -276,6 +276,18 @@ struct alc_mic_route {
276 276
277#define MUX_IDX_UNDEF ((unsigned char)-1) 277#define MUX_IDX_UNDEF ((unsigned char)-1)
278 278
279struct alc_customize_define {
280 unsigned int sku_cfg;
281 unsigned char port_connectivity;
282 unsigned char check_sum;
283 unsigned char customization;
284 unsigned char external_amp;
285 unsigned int enable_pcbeep:1;
286 unsigned int platform_type:1;
287 unsigned int swap:1;
288 unsigned int override:1;
289};
290
279struct alc_spec { 291struct alc_spec {
280 /* codec parameterization */ 292 /* codec parameterization */
281 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 293 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -333,6 +345,7 @@ struct alc_spec {
333 345
334 /* dynamic controls, init_verbs and input_mux */ 346 /* dynamic controls, init_verbs and input_mux */
335 struct auto_pin_cfg autocfg; 347 struct auto_pin_cfg autocfg;
348 struct alc_customize_define cdefine;
336 struct snd_array kctls; 349 struct snd_array kctls;
337 struct hda_input_mux private_imux[3]; 350 struct hda_input_mux private_imux[3];
338 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 351 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
@@ -1248,6 +1261,62 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1248 spec->unsol_event = alc_sku_unsol_event; 1261 spec->unsol_event = alc_sku_unsol_event;
1249} 1262}
1250 1263
1264static int alc_auto_parse_customize_define(struct hda_codec *codec)
1265{
1266 unsigned int ass, tmp, i;
1267 unsigned nid = 0;
1268 struct alc_spec *spec = codec->spec;
1269
1270 ass = codec->subsystem_id & 0xffff;
1271 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1272 goto do_sku;
1273
1274 nid = 0x1d;
1275 if (codec->vendor_id == 0x10ec0260)
1276 nid = 0x17;
1277 ass = snd_hda_codec_get_pincfg(codec, nid);
1278
1279 if (!(ass & 1)) {
1280 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1281 codec->chip_name, ass);
1282 return -1;
1283 }
1284
1285 /* check sum */
1286 tmp = 0;
1287 for (i = 1; i < 16; i++) {
1288 if ((ass >> i) & 1)
1289 tmp++;
1290 }
1291 if (((ass >> 16) & 0xf) != tmp)
1292 return -1;
1293
1294 spec->cdefine.port_connectivity = ass >> 30;
1295 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1296 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1297 spec->cdefine.customization = ass >> 8;
1298do_sku:
1299 spec->cdefine.sku_cfg = ass;
1300 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1301 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1302 spec->cdefine.swap = (ass & 0x2) >> 1;
1303 spec->cdefine.override = ass & 0x1;
1304
1305 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1306 nid, spec->cdefine.sku_cfg);
1307 snd_printd("SKU: port_connectivity=0x%x\n",
1308 spec->cdefine.port_connectivity);
1309 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1310 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1311 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1312 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1313 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1314 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1315 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1316
1317 return 0;
1318}
1319
1251/* check subsystem ID and set up device-specific initialization; 1320/* check subsystem ID and set up device-specific initialization;
1252 * return 1 if initialized, 0 if invalid SSID 1321 * return 1 if initialized, 0 if invalid SSID
1253 */ 1322 */
@@ -3415,6 +3484,10 @@ static int alc_init(struct hda_codec *codec)
3415 if (spec->init_hook) 3484 if (spec->init_hook)
3416 spec->init_hook(codec); 3485 spec->init_hook(codec);
3417 3486
3487#ifdef CONFIG_SND_HDA_POWER_SAVE
3488 if (codec->patch_ops.check_power_status)
3489 codec->patch_ops.check_power_status(codec, 0x01);
3490#endif
3418 return 0; 3491 return 0;
3419} 3492}
3420 3493
@@ -3775,6 +3848,10 @@ static int alc_resume(struct hda_codec *codec)
3775 codec->patch_ops.init(codec); 3848 codec->patch_ops.init(codec);
3776 snd_hda_codec_resume_amp(codec); 3849 snd_hda_codec_resume_amp(codec);
3777 snd_hda_codec_resume_cache(codec); 3850 snd_hda_codec_resume_cache(codec);
3851#ifdef CONFIG_SND_HDA_POWER_SAVE
3852 if (codec->patch_ops.check_power_status)
3853 codec->patch_ops.check_power_status(codec, 0x01);
3854#endif
3778 return 0; 3855 return 0;
3779} 3856}
3780#endif 3857#endif
@@ -3797,6 +3874,17 @@ static struct hda_codec_ops alc_patch_ops = {
3797 .reboot_notify = alc_shutup, 3874 .reboot_notify = alc_shutup,
3798}; 3875};
3799 3876
3877/* replace the codec chip_name with the given string */
3878static int alc_codec_rename(struct hda_codec *codec, const char *name)
3879{
3880 kfree(codec->chip_name);
3881 codec->chip_name = kstrdup(name, GFP_KERNEL);
3882 if (!codec->chip_name) {
3883 alc_free(codec);
3884 return -ENOMEM;
3885 }
3886 return 0;
3887}
3800 3888
3801/* 3889/*
3802 * Test configuration for debugging 3890 * Test configuration for debugging
@@ -10189,21 +10277,20 @@ static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10189 10277
10190static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10278static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10191 hda_nid_t nid, int pin_type, 10279 hda_nid_t nid, int pin_type,
10192 int dac_idx) 10280 hda_nid_t dac)
10193{ 10281{
10194 /* set as output */
10195 struct alc_spec *spec = codec->spec;
10196 int idx; 10282 int idx;
10197 10283
10284 /* set as output */
10198 alc_set_pin_output(codec, nid, pin_type); 10285 alc_set_pin_output(codec, nid, pin_type);
10199 if (dac_idx >= spec->multiout.num_dacs) 10286
10200 return; 10287 if (dac == 0x25)
10201 if (spec->multiout.dac_nids[dac_idx] == 0x25)
10202 idx = 4; 10288 idx = 4;
10289 else if (dac >= 0x02 && dac <= 0x05)
10290 idx = dac - 2;
10203 else 10291 else
10204 idx = spec->multiout.dac_nids[dac_idx] - 2; 10292 return;
10205 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10293 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10206
10207} 10294}
10208 10295
10209static void alc882_auto_init_multi_out(struct hda_codec *codec) 10296static void alc882_auto_init_multi_out(struct hda_codec *codec)
@@ -10216,22 +10303,29 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
10216 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10303 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10217 if (nid) 10304 if (nid)
10218 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10305 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10219 i); 10306 spec->multiout.dac_nids[i]);
10220 } 10307 }
10221} 10308}
10222 10309
10223static void alc882_auto_init_hp_out(struct hda_codec *codec) 10310static void alc882_auto_init_hp_out(struct hda_codec *codec)
10224{ 10311{
10225 struct alc_spec *spec = codec->spec; 10312 struct alc_spec *spec = codec->spec;
10226 hda_nid_t pin; 10313 hda_nid_t pin, dac;
10227 10314
10228 pin = spec->autocfg.hp_pins[0]; 10315 pin = spec->autocfg.hp_pins[0];
10229 if (pin) /* connect to front */ 10316 if (pin) {
10230 /* use dac 0 */ 10317 dac = spec->multiout.hp_nid;
10231 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 10318 if (!dac)
10319 dac = spec->multiout.dac_nids[0]; /* to front */
10320 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10321 }
10232 pin = spec->autocfg.speaker_pins[0]; 10322 pin = spec->autocfg.speaker_pins[0];
10233 if (pin) 10323 if (pin) {
10234 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 10324 dac = spec->multiout.extra_out_nid[0];
10325 if (!dac)
10326 dac = spec->multiout.dac_nids[0]; /* to front */
10327 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10328 }
10235} 10329}
10236 10330
10237static void alc882_auto_init_analog_input(struct hda_codec *codec) 10331static void alc882_auto_init_analog_input(struct hda_codec *codec)
@@ -10347,15 +10441,15 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10347 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10441 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10348 if (err < 0) 10442 if (err < 0)
10349 return err; 10443 return err;
10444 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10445 "Headphone");
10446 if (err < 0)
10447 return err;
10350 err = alc880_auto_create_extra_out(spec, 10448 err = alc880_auto_create_extra_out(spec,
10351 spec->autocfg.speaker_pins[0], 10449 spec->autocfg.speaker_pins[0],
10352 "Speaker"); 10450 "Speaker");
10353 if (err < 0) 10451 if (err < 0)
10354 return err; 10452 return err;
10355 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10356 "Headphone");
10357 if (err < 0)
10358 return err;
10359 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10453 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10360 if (err < 0) 10454 if (err < 0)
10361 return err; 10455 return err;
@@ -10425,6 +10519,8 @@ static int patch_alc882(struct hda_codec *codec)
10425 10519
10426 codec->spec = spec; 10520 codec->spec = spec;
10427 10521
10522 alc_auto_parse_customize_define(codec);
10523
10428 switch (codec->vendor_id) { 10524 switch (codec->vendor_id) {
10429 case 0x10ec0882: 10525 case 0x10ec0882:
10430 case 0x10ec0885: 10526 case 0x10ec0885:
@@ -10484,9 +10580,6 @@ static int patch_alc882(struct hda_codec *codec)
10484 spec->stream_digital_playback = &alc882_pcm_digital_playback; 10580 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10485 spec->stream_digital_capture = &alc882_pcm_digital_capture; 10581 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10486 10582
10487 if (codec->vendor_id == 0x10ec0888)
10488 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
10489
10490 if (!spec->adc_nids && spec->input_mux) { 10583 if (!spec->adc_nids && spec->input_mux) {
10491 int i, j; 10584 int i, j;
10492 spec->num_adc_nids = 0; 10585 spec->num_adc_nids = 0;
@@ -10521,7 +10614,9 @@ static int patch_alc882(struct hda_codec *codec)
10521 } 10614 }
10522 10615
10523 set_capture_mixer(codec); 10616 set_capture_mixer(codec);
10524 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10617
10618 if (spec->cdefine.enable_pcbeep)
10619 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10525 10620
10526 if (board_config == ALC882_AUTO) 10621 if (board_config == ALC882_AUTO)
10527 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); 10622 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
@@ -12308,6 +12403,7 @@ static int patch_alc262(struct hda_codec *codec)
12308 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12403 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12309 } 12404 }
12310#endif 12405#endif
12406 alc_auto_parse_customize_define(codec);
12311 12407
12312 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12408 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12313 12409
@@ -12386,7 +12482,7 @@ static int patch_alc262(struct hda_codec *codec)
12386 } 12482 }
12387 if (!spec->cap_mixer && !spec->no_analog) 12483 if (!spec->cap_mixer && !spec->no_analog)
12388 set_capture_mixer(codec); 12484 set_capture_mixer(codec);
12389 if (!spec->no_analog) 12485 if (!spec->no_analog && spec->cdefine.enable_pcbeep)
12390 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 12486 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12391 12487
12392 spec->vmaster_nid = 0x0c; 12488 spec->vmaster_nid = 0x0c;
@@ -14005,6 +14101,35 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14005 /* NID is set in alc_build_pcms */ 14101 /* NID is set in alc_build_pcms */
14006}; 14102};
14007 14103
14104#ifdef CONFIG_SND_HDA_POWER_SAVE
14105static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14106{
14107 switch (codec->subsystem_id) {
14108 case 0x103c1586:
14109 return 1;
14110 }
14111 return 0;
14112}
14113
14114static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14115{
14116 /* update mute-LED according to the speaker mute state */
14117 if (nid == 0x01 || nid == 0x14) {
14118 int pinval;
14119 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14120 HDA_AMP_MUTE)
14121 pinval = 0x24;
14122 else
14123 pinval = 0x20;
14124 /* mic2 vref pin is used for mute LED control */
14125 snd_hda_codec_update_cache(codec, 0x19, 0,
14126 AC_VERB_SET_PIN_WIDGET_CONTROL,
14127 pinval);
14128 }
14129 return alc_check_power_status(codec, nid);
14130}
14131#endif /* CONFIG_SND_HDA_POWER_SAVE */
14132
14008/* 14133/*
14009 * BIOS auto configuration 14134 * BIOS auto configuration
14010 */ 14135 */
@@ -14082,7 +14207,7 @@ enum {
14082 ALC269_FIXUP_SONY_VAIO, 14207 ALC269_FIXUP_SONY_VAIO,
14083}; 14208};
14084 14209
14085const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = { 14210static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
14086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14211 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14087 {} 14212 {}
14088}; 14213};
@@ -14290,17 +14415,17 @@ static int patch_alc269(struct hda_codec *codec)
14290 14415
14291 codec->spec = spec; 14416 codec->spec = spec;
14292 14417
14293 alc_fix_pll_init(codec, 0x20, 0x04, 15); 14418 alc_auto_parse_customize_define(codec);
14294 14419
14295 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 14420 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14296 kfree(codec->chip_name); 14421 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14297 codec->chip_name = kstrdup("ALC259", GFP_KERNEL); 14422 spec->cdefine.platform_type == 1)
14298 if (!codec->chip_name) { 14423 alc_codec_rename(codec, "ALC271X");
14299 alc_free(codec); 14424 else
14300 return -ENOMEM; 14425 alc_codec_rename(codec, "ALC259");
14301 }
14302 is_alc269vb = 1; 14426 is_alc269vb = 1;
14303 } 14427 } else
14428 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14304 14429
14305 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14430 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14306 alc269_models, 14431 alc269_models,
@@ -14365,7 +14490,8 @@ static int patch_alc269(struct hda_codec *codec)
14365 14490
14366 if (!spec->cap_mixer) 14491 if (!spec->cap_mixer)
14367 set_capture_mixer(codec); 14492 set_capture_mixer(codec);
14368 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14493 if (spec->cdefine.enable_pcbeep)
14494 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14369 14495
14370 if (board_config == ALC269_AUTO) 14496 if (board_config == ALC269_AUTO)
14371 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); 14497 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
@@ -14378,6 +14504,8 @@ static int patch_alc269(struct hda_codec *codec)
14378#ifdef CONFIG_SND_HDA_POWER_SAVE 14504#ifdef CONFIG_SND_HDA_POWER_SAVE
14379 if (!spec->loopback.amplist) 14505 if (!spec->loopback.amplist)
14380 spec->loopback.amplist = alc269_loopbacks; 14506 spec->loopback.amplist = alc269_loopbacks;
14507 if (alc269_mic2_for_mute_led(codec))
14508 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
14381#endif 14509#endif
14382 14510
14383 return 0; 14511 return 0;
@@ -18525,16 +18653,16 @@ static int patch_alc662(struct hda_codec *codec)
18525 18653
18526 codec->spec = spec; 18654 codec->spec = spec;
18527 18655
18656 alc_auto_parse_customize_define(codec);
18657
18528 alc_fix_pll_init(codec, 0x20, 0x04, 15); 18658 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18529 18659
18530 if (alc_read_coef_idx(codec, 0)==0x8020){ 18660 if (alc_read_coef_idx(codec, 0) == 0x8020)
18531 kfree(codec->chip_name); 18661 alc_codec_rename(codec, "ALC661");
18532 codec->chip_name = kstrdup("ALC661", GFP_KERNEL); 18662 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18533 if (!codec->chip_name) { 18663 codec->bus->pci->subsystem_vendor == 0x1025 &&
18534 alc_free(codec); 18664 spec->cdefine.platform_type == 1)
18535 return -ENOMEM; 18665 alc_codec_rename(codec, "ALC272X");
18536 }
18537 }
18538 18666
18539 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 18667 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18540 alc662_models, 18668 alc662_models,
@@ -18584,18 +18712,20 @@ static int patch_alc662(struct hda_codec *codec)
18584 if (!spec->cap_mixer) 18712 if (!spec->cap_mixer)
18585 set_capture_mixer(codec); 18713 set_capture_mixer(codec);
18586 18714
18587 switch (codec->vendor_id) { 18715 if (spec->cdefine.enable_pcbeep) {
18588 case 0x10ec0662: 18716 switch (codec->vendor_id) {
18589 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18717 case 0x10ec0662:
18590 break; 18718 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18591 case 0x10ec0272: 18719 break;
18592 case 0x10ec0663: 18720 case 0x10ec0272:
18593 case 0x10ec0665: 18721 case 0x10ec0663:
18594 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18722 case 0x10ec0665:
18595 break; 18723 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18596 case 0x10ec0273: 18724 break;
18597 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 18725 case 0x10ec0273:
18598 break; 18726 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18727 break;
18728 }
18599 } 18729 }
18600 spec->vmaster_nid = 0x02; 18730 spec->vmaster_nid = 0x02;
18601 18731
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 9e66f6d306f8..2f6252266a02 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1956,11 +1956,10 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1956 return 0; 1956 return 0;
1957} 1957}
1958 1958
1959
1960/* 1959/*
1961 * initialize the chip 1960 * reset the chip
1962 */ 1961 */
1963static int __devinit aureon_init(struct snd_ice1712 *ice) 1962static int aureon_reset(struct snd_ice1712 *ice)
1964{ 1963{
1965 static const unsigned short wm_inits_aureon[] = { 1964 static const unsigned short wm_inits_aureon[] = {
1966 /* These come first to reduce init pop noise */ 1965 /* These come first to reduce init pop noise */
@@ -2047,30 +2046,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2047 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */ 2046 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2048 (unsigned short)-1 2047 (unsigned short)-1
2049 }; 2048 };
2050 struct aureon_spec *spec;
2051 unsigned int tmp; 2049 unsigned int tmp;
2052 const unsigned short *p; 2050 const unsigned short *p;
2053 int err, i; 2051 int err;
2054 2052 struct aureon_spec *spec = ice->spec;
2055 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2056 if (!spec)
2057 return -ENOMEM;
2058 ice->spec = spec;
2059
2060 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2061 ice->num_total_dacs = 6;
2062 ice->num_total_adcs = 2;
2063 } else {
2064 /* aureon 7.1 and prodigy 7.1 */
2065 ice->num_total_dacs = 8;
2066 ice->num_total_adcs = 2;
2067 }
2068
2069 /* to remeber the register values of CS8415 */
2070 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2071 if (!ice->akm)
2072 return -ENOMEM;
2073 ice->akm_codecs = 1;
2074 2053
2075 err = aureon_ac97_init(ice); 2054 err = aureon_ac97_init(ice);
2076 if (err != 0) 2055 if (err != 0)
@@ -2118,6 +2097,61 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2118 /* initialize PCA9554 pin directions & set default input */ 2097 /* initialize PCA9554 pin directions & set default input */
2119 aureon_pca9554_write(ice, PCA9554_DIR, 0x00); 2098 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2120 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ 2099 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2100 return 0;
2101}
2102
2103/*
2104 * suspend/resume
2105 */
2106#ifdef CONFIG_PM
2107static int aureon_resume(struct snd_ice1712 *ice)
2108{
2109 struct aureon_spec *spec = ice->spec;
2110 int err, i;
2111
2112 err = aureon_reset(ice);
2113 if (err != 0)
2114 return err;
2115
2116 /* workaround for poking volume with alsamixer after resume:
2117 * just set stored volume again */
2118 for (i = 0; i < ice->num_total_dacs; i++)
2119 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2120 return 0;
2121}
2122#endif
2123
2124/*
2125 * initialize the chip
2126 */
2127static int __devinit aureon_init(struct snd_ice1712 *ice)
2128{
2129 struct aureon_spec *spec;
2130 int i, err;
2131
2132 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2133 if (!spec)
2134 return -ENOMEM;
2135 ice->spec = spec;
2136
2137 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2138 ice->num_total_dacs = 6;
2139 ice->num_total_adcs = 2;
2140 } else {
2141 /* aureon 7.1 and prodigy 7.1 */
2142 ice->num_total_dacs = 8;
2143 ice->num_total_adcs = 2;
2144 }
2145
2146 /* to remeber the register values of CS8415 */
2147 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
2148 if (!ice->akm)
2149 return -ENOMEM;
2150 ice->akm_codecs = 1;
2151
2152 err = aureon_reset(ice);
2153 if (err != 0)
2154 return err;
2121 2155
2122 spec->master[0] = WM_VOL_MUTE; 2156 spec->master[0] = WM_VOL_MUTE;
2123 spec->master[1] = WM_VOL_MUTE; 2157 spec->master[1] = WM_VOL_MUTE;
@@ -2126,6 +2160,11 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2126 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); 2160 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2127 } 2161 }
2128 2162
2163#ifdef CONFIG_PM
2164 ice->pm_resume = aureon_resume;
2165 ice->pm_suspend_enabled = 1;
2166#endif
2167
2129 return 0; 2168 return 0;
2130} 2169}
2131 2170
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index b56e33676780..3c40d726b46e 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -41,6 +41,7 @@
41#include <linux/vmalloc.h> 41#include <linux/vmalloc.h>
42#include <linux/moduleparam.h> 42#include <linux/moduleparam.h>
43#include <linux/firmware.h> 43#include <linux/firmware.h>
44#include <linux/input.h>
44#include <sound/core.h> 45#include <sound/core.h>
45#include <sound/info.h> 46#include <sound/info.h>
46#include <sound/control.h> 47#include <sound/control.h>
@@ -844,11 +845,17 @@ struct snd_m3 {
844 struct m3_dma *substreams; 845 struct m3_dma *substreams;
845 846
846 spinlock_t reg_lock; 847 spinlock_t reg_lock;
847 spinlock_t ac97_lock;
848 848
849#ifdef CONFIG_SND_MAESTRO3_INPUT
850 struct input_dev *input_dev;
851 char phys[64]; /* physical device path */
852#else
853 spinlock_t ac97_lock;
849 struct snd_kcontrol *master_switch; 854 struct snd_kcontrol *master_switch;
850 struct snd_kcontrol *master_volume; 855 struct snd_kcontrol *master_volume;
851 struct tasklet_struct hwvol_tq; 856 struct tasklet_struct hwvol_tq;
857#endif
858
852 unsigned int in_suspend; 859 unsigned int in_suspend;
853 860
854#ifdef CONFIG_PM 861#ifdef CONFIG_PM
@@ -1598,18 +1605,32 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
1598 } 1605 }
1599} 1606}
1600 1607
1608/* The m3's hardware volume works by incrementing / decrementing 2 counters
1609 (without wrap around) in response to volume button presses and then
1610 generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
1611 of a byte wide register. The meaning of bits 0 and 4 is unknown. */
1601static void snd_m3_update_hw_volume(unsigned long private_data) 1612static void snd_m3_update_hw_volume(unsigned long private_data)
1602{ 1613{
1603 struct snd_m3 *chip = (struct snd_m3 *) private_data; 1614 struct snd_m3 *chip = (struct snd_m3 *) private_data;
1604 int x, val; 1615 int x, val;
1616#ifndef CONFIG_SND_MAESTRO3_INPUT
1605 unsigned long flags; 1617 unsigned long flags;
1618#endif
1606 1619
1607 /* Figure out which volume control button was pushed, 1620 /* Figure out which volume control button was pushed,
1608 based on differences from the default register 1621 based on differences from the default register
1609 values. */ 1622 values. */
1610 x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee; 1623 x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee;
1611 1624
1612 /* Reset the volume control registers. */ 1625 /* Reset the volume counters to 4. Tests on the allegro integrated
1626 into a Compaq N600C laptop, have revealed that:
1627 1) Writing any value will result in the 2 counters being reset to
1628 4 so writing 0x88 is not strictly necessary
1629 2) Writing to any of the 4 involved registers will reset all 4
1630 of them (and reading them always returns the same value for all
1631 of them)
1632 It could be that a maestro deviates from this, so leave the code
1633 as is. */
1613 outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE); 1634 outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE);
1614 outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE); 1635 outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE);
1615 outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); 1636 outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
@@ -1620,6 +1641,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1620 if (chip->in_suspend) 1641 if (chip->in_suspend)
1621 return; 1642 return;
1622 1643
1644#ifndef CONFIG_SND_MAESTRO3_INPUT
1623 if (!chip->master_switch || !chip->master_volume) 1645 if (!chip->master_switch || !chip->master_volume)
1624 return; 1646 return;
1625 1647
@@ -1629,7 +1651,9 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1629 val = chip->ac97->regs[AC97_MASTER_VOL]; 1651 val = chip->ac97->regs[AC97_MASTER_VOL];
1630 switch (x) { 1652 switch (x) {
1631 case 0x88: 1653 case 0x88:
1632 /* mute */ 1654 /* The counters have not changed, yet we've received a HV
1655 interrupt. According to tests run by various people this
1656 happens when pressing the mute button. */
1633 val ^= 0x8000; 1657 val ^= 0x8000;
1634 chip->ac97->regs[AC97_MASTER_VOL] = val; 1658 chip->ac97->regs[AC97_MASTER_VOL] = val;
1635 outw(val, chip->iobase + CODEC_DATA); 1659 outw(val, chip->iobase + CODEC_DATA);
@@ -1638,7 +1662,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1638 &chip->master_switch->id); 1662 &chip->master_switch->id);
1639 break; 1663 break;
1640 case 0xaa: 1664 case 0xaa:
1641 /* volume up */ 1665 /* counters increased by 1 -> volume up */
1642 if ((val & 0x7f) > 0) 1666 if ((val & 0x7f) > 0)
1643 val--; 1667 val--;
1644 if ((val & 0x7f00) > 0) 1668 if ((val & 0x7f00) > 0)
@@ -1650,7 +1674,7 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1650 &chip->master_volume->id); 1674 &chip->master_volume->id);
1651 break; 1675 break;
1652 case 0x66: 1676 case 0x66:
1653 /* volume down */ 1677 /* counters decreased by 1 -> volume down */
1654 if ((val & 0x7f) < 0x1f) 1678 if ((val & 0x7f) < 0x1f)
1655 val++; 1679 val++;
1656 if ((val & 0x7f00) < 0x1f00) 1680 if ((val & 0x7f00) < 0x1f00)
@@ -1663,6 +1687,35 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
1663 break; 1687 break;
1664 } 1688 }
1665 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1689 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1690#else
1691 if (!chip->input_dev)
1692 return;
1693
1694 val = 0;
1695 switch (x) {
1696 case 0x88:
1697 /* The counters have not changed, yet we've received a HV
1698 interrupt. According to tests run by various people this
1699 happens when pressing the mute button. */
1700 val = KEY_MUTE;
1701 break;
1702 case 0xaa:
1703 /* counters increased by 1 -> volume up */
1704 val = KEY_VOLUMEUP;
1705 break;
1706 case 0x66:
1707 /* counters decreased by 1 -> volume down */
1708 val = KEY_VOLUMEDOWN;
1709 break;
1710 }
1711
1712 if (val) {
1713 input_report_key(chip->input_dev, val, 1);
1714 input_sync(chip->input_dev);
1715 input_report_key(chip->input_dev, val, 0);
1716 input_sync(chip->input_dev);
1717 }
1718#endif
1666} 1719}
1667 1720
1668static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) 1721static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
@@ -1677,7 +1730,11 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
1677 return IRQ_NONE; 1730 return IRQ_NONE;
1678 1731
1679 if (status & HV_INT_PENDING) 1732 if (status & HV_INT_PENDING)
1733#ifdef CONFIG_SND_MAESTRO3_INPUT
1734 snd_m3_update_hw_volume((unsigned long)chip);
1735#else
1680 tasklet_schedule(&chip->hwvol_tq); 1736 tasklet_schedule(&chip->hwvol_tq);
1737#endif
1681 1738
1682 /* 1739 /*
1683 * ack an assp int if its running 1740 * ack an assp int if its running
@@ -1943,18 +2000,24 @@ static unsigned short
1943snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 2000snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
1944{ 2001{
1945 struct snd_m3 *chip = ac97->private_data; 2002 struct snd_m3 *chip = ac97->private_data;
2003#ifndef CONFIG_SND_MAESTRO3_INPUT
1946 unsigned long flags; 2004 unsigned long flags;
2005#endif
1947 unsigned short data = 0xffff; 2006 unsigned short data = 0xffff;
1948 2007
1949 if (snd_m3_ac97_wait(chip)) 2008 if (snd_m3_ac97_wait(chip))
1950 goto fail; 2009 goto fail;
2010#ifndef CONFIG_SND_MAESTRO3_INPUT
1951 spin_lock_irqsave(&chip->ac97_lock, flags); 2011 spin_lock_irqsave(&chip->ac97_lock, flags);
2012#endif
1952 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); 2013 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
1953 if (snd_m3_ac97_wait(chip)) 2014 if (snd_m3_ac97_wait(chip))
1954 goto fail_unlock; 2015 goto fail_unlock;
1955 data = snd_m3_inw(chip, CODEC_DATA); 2016 data = snd_m3_inw(chip, CODEC_DATA);
1956fail_unlock: 2017fail_unlock:
2018#ifndef CONFIG_SND_MAESTRO3_INPUT
1957 spin_unlock_irqrestore(&chip->ac97_lock, flags); 2019 spin_unlock_irqrestore(&chip->ac97_lock, flags);
2020#endif
1958fail: 2021fail:
1959 return data; 2022 return data;
1960} 2023}
@@ -1963,14 +2026,20 @@ static void
1963snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 2026snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
1964{ 2027{
1965 struct snd_m3 *chip = ac97->private_data; 2028 struct snd_m3 *chip = ac97->private_data;
2029#ifndef CONFIG_SND_MAESTRO3_INPUT
1966 unsigned long flags; 2030 unsigned long flags;
2031#endif
1967 2032
1968 if (snd_m3_ac97_wait(chip)) 2033 if (snd_m3_ac97_wait(chip))
1969 return; 2034 return;
2035#ifndef CONFIG_SND_MAESTRO3_INPUT
1970 spin_lock_irqsave(&chip->ac97_lock, flags); 2036 spin_lock_irqsave(&chip->ac97_lock, flags);
2037#endif
1971 snd_m3_outw(chip, val, CODEC_DATA); 2038 snd_m3_outw(chip, val, CODEC_DATA);
1972 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND); 2039 snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
2040#ifndef CONFIG_SND_MAESTRO3_INPUT
1973 spin_unlock_irqrestore(&chip->ac97_lock, flags); 2041 spin_unlock_irqrestore(&chip->ac97_lock, flags);
2042#endif
1974} 2043}
1975 2044
1976 2045
@@ -2077,7 +2146,9 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2077{ 2146{
2078 struct snd_ac97_bus *pbus; 2147 struct snd_ac97_bus *pbus;
2079 struct snd_ac97_template ac97; 2148 struct snd_ac97_template ac97;
2149#ifndef CONFIG_SND_MAESTRO3_INPUT
2080 struct snd_ctl_elem_id elem_id; 2150 struct snd_ctl_elem_id elem_id;
2151#endif
2081 int err; 2152 int err;
2082 static struct snd_ac97_bus_ops ops = { 2153 static struct snd_ac97_bus_ops ops = {
2083 .write = snd_m3_ac97_write, 2154 .write = snd_m3_ac97_write,
@@ -2097,6 +2168,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2097 schedule_timeout_uninterruptible(msecs_to_jiffies(100)); 2168 schedule_timeout_uninterruptible(msecs_to_jiffies(100));
2098 snd_ac97_write(chip->ac97, AC97_PCM, 0); 2169 snd_ac97_write(chip->ac97, AC97_PCM, 0);
2099 2170
2171#ifndef CONFIG_SND_MAESTRO3_INPUT
2100 memset(&elem_id, 0, sizeof(elem_id)); 2172 memset(&elem_id, 0, sizeof(elem_id));
2101 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2173 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2102 strcpy(elem_id.name, "Master Playback Switch"); 2174 strcpy(elem_id.name, "Master Playback Switch");
@@ -2105,6 +2177,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2105 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 2177 elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2106 strcpy(elem_id.name, "Master Playback Volume"); 2178 strcpy(elem_id.name, "Master Playback Volume");
2107 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); 2179 chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
2180#endif
2108 2181
2109 return 0; 2182 return 0;
2110} 2183}
@@ -2370,6 +2443,7 @@ snd_m3_enable_ints(struct snd_m3 *chip)
2370 val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; 2443 val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/;
2371 if (chip->hv_config & HV_CTRL_ENABLE) 2444 if (chip->hv_config & HV_CTRL_ENABLE)
2372 val |= HV_INT_ENABLE; 2445 val |= HV_INT_ENABLE;
2446 outb(val, chip->iobase + HOST_INT_STATUS);
2373 outw(val, io + HOST_INT_CTRL); 2447 outw(val, io + HOST_INT_CTRL);
2374 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, 2448 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
2375 io + ASSP_CONTROL_C); 2449 io + ASSP_CONTROL_C);
@@ -2384,6 +2458,11 @@ static int snd_m3_free(struct snd_m3 *chip)
2384 struct m3_dma *s; 2458 struct m3_dma *s;
2385 int i; 2459 int i;
2386 2460
2461#ifdef CONFIG_SND_MAESTRO3_INPUT
2462 if (chip->input_dev)
2463 input_unregister_device(chip->input_dev);
2464#endif
2465
2387 if (chip->substreams) { 2466 if (chip->substreams) {
2388 spin_lock_irq(&chip->reg_lock); 2467 spin_lock_irq(&chip->reg_lock);
2389 for (i = 0; i < chip->num_substreams; i++) { 2468 for (i = 0; i < chip->num_substreams; i++) {
@@ -2510,6 +2589,41 @@ static int m3_resume(struct pci_dev *pci)
2510} 2589}
2511#endif /* CONFIG_PM */ 2590#endif /* CONFIG_PM */
2512 2591
2592#ifdef CONFIG_SND_MAESTRO3_INPUT
2593static int __devinit snd_m3_input_register(struct snd_m3 *chip)
2594{
2595 struct input_dev *input_dev;
2596 int err;
2597
2598 input_dev = input_allocate_device();
2599 if (!input_dev)
2600 return -ENOMEM;
2601
2602 snprintf(chip->phys, sizeof(chip->phys), "pci-%s/input0",
2603 pci_name(chip->pci));
2604
2605 input_dev->name = chip->card->driver;
2606 input_dev->phys = chip->phys;
2607 input_dev->id.bustype = BUS_PCI;
2608 input_dev->id.vendor = chip->pci->vendor;
2609 input_dev->id.product = chip->pci->device;
2610 input_dev->dev.parent = &chip->pci->dev;
2611
2612 __set_bit(EV_KEY, input_dev->evbit);
2613 __set_bit(KEY_MUTE, input_dev->keybit);
2614 __set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
2615 __set_bit(KEY_VOLUMEUP, input_dev->keybit);
2616
2617 err = input_register_device(input_dev);
2618 if (err) {
2619 input_free_device(input_dev);
2620 return err;
2621 }
2622
2623 chip->input_dev = input_dev;
2624 return 0;
2625}
2626#endif /* CONFIG_INPUT */
2513 2627
2514/* 2628/*
2515 */ 2629 */
@@ -2553,7 +2667,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2553 } 2667 }
2554 2668
2555 spin_lock_init(&chip->reg_lock); 2669 spin_lock_init(&chip->reg_lock);
2670#ifndef CONFIG_SND_MAESTRO3_INPUT
2556 spin_lock_init(&chip->ac97_lock); 2671 spin_lock_init(&chip->ac97_lock);
2672#endif
2557 2673
2558 switch (pci->device) { 2674 switch (pci->device) {
2559 case PCI_DEVICE_ID_ESS_ALLEGRO: 2675 case PCI_DEVICE_ID_ESS_ALLEGRO:
@@ -2636,7 +2752,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2636 2752
2637 snd_m3_hv_init(chip); 2753 snd_m3_hv_init(chip);
2638 2754
2755#ifndef CONFIG_SND_MAESTRO3_INPUT
2639 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); 2756 tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
2757#endif
2640 2758
2641 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, 2759 if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
2642 card->driver, chip)) { 2760 card->driver, chip)) {
@@ -2668,7 +2786,16 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2668 2786
2669 if ((err = snd_m3_pcm(chip, 0)) < 0) 2787 if ((err = snd_m3_pcm(chip, 0)) < 0)
2670 return err; 2788 return err;
2671 2789
2790#ifdef CONFIG_SND_MAESTRO3_INPUT
2791 if (chip->hv_config & HV_CTRL_ENABLE) {
2792 err = snd_m3_input_register(chip);
2793 if (err)
2794 snd_printk(KERN_WARNING "Input device registration "
2795 "failed with error %i", err);
2796 }
2797#endif
2798
2672 snd_m3_enable_ints(chip); 2799 snd_m3_enable_ints(chip);
2673 snd_m3_assp_continue(chip); 2800 snd_m3_assp_continue(chip);
2674 2801
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 3be8f97c8bc0..6c3fd4d1c49d 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1102,73 +1102,17 @@ static int snd_mixart_free(struct mixart_mgr *mgr)
1102/* 1102/*
1103 * proc interface 1103 * proc interface
1104 */ 1104 */
1105static long long snd_mixart_BA0_llseek(struct snd_info_entry *entry,
1106 void *private_file_data,
1107 struct file *file,
1108 long long offset,
1109 int orig)
1110{
1111 offset = offset & ~3; /* 4 bytes aligned */
1112
1113 switch(orig) {
1114 case SEEK_SET:
1115 file->f_pos = offset;
1116 break;
1117 case SEEK_CUR:
1118 file->f_pos += offset;
1119 break;
1120 case SEEK_END: /* offset is negative */
1121 file->f_pos = MIXART_BA0_SIZE + offset;
1122 break;
1123 default:
1124 return -EINVAL;
1125 }
1126 if(file->f_pos > MIXART_BA0_SIZE)
1127 file->f_pos = MIXART_BA0_SIZE;
1128 return file->f_pos;
1129}
1130
1131static long long snd_mixart_BA1_llseek(struct snd_info_entry *entry,
1132 void *private_file_data,
1133 struct file *file,
1134 long long offset,
1135 int orig)
1136{
1137 offset = offset & ~3; /* 4 bytes aligned */
1138
1139 switch(orig) {
1140 case SEEK_SET:
1141 file->f_pos = offset;
1142 break;
1143 case SEEK_CUR:
1144 file->f_pos += offset;
1145 break;
1146 case SEEK_END: /* offset is negative */
1147 file->f_pos = MIXART_BA1_SIZE + offset;
1148 break;
1149 default:
1150 return -EINVAL;
1151 }
1152 if(file->f_pos > MIXART_BA1_SIZE)
1153 file->f_pos = MIXART_BA1_SIZE;
1154 return file->f_pos;
1155}
1156 1105
1157/* 1106/*
1158 mixart_BA0 proc interface for BAR 0 - read callback 1107 mixart_BA0 proc interface for BAR 0 - read callback
1159 */ 1108 */
1160static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private_data, 1109static ssize_t snd_mixart_BA0_read(struct snd_info_entry *entry,
1161 struct file *file, char __user *buf, 1110 void *file_private_data,
1162 unsigned long count, unsigned long pos) 1111 struct file *file, char __user *buf,
1112 size_t count, loff_t pos)
1163{ 1113{
1164 struct mixart_mgr *mgr = entry->private_data; 1114 struct mixart_mgr *mgr = entry->private_data;
1165 unsigned long maxsize;
1166 1115
1167 if (pos >= MIXART_BA0_SIZE)
1168 return 0;
1169 maxsize = MIXART_BA0_SIZE - pos;
1170 if (count > maxsize)
1171 count = maxsize;
1172 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1116 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1173 if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count)) 1117 if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
1174 return -EFAULT; 1118 return -EFAULT;
@@ -1178,18 +1122,13 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
1178/* 1122/*
1179 mixart_BA1 proc interface for BAR 1 - read callback 1123 mixart_BA1 proc interface for BAR 1 - read callback
1180 */ 1124 */
1181static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private_data, 1125static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry,
1182 struct file *file, char __user *buf, 1126 void *file_private_data,
1183 unsigned long count, unsigned long pos) 1127 struct file *file, char __user *buf,
1128 size_t count, loff_t pos)
1184{ 1129{
1185 struct mixart_mgr *mgr = entry->private_data; 1130 struct mixart_mgr *mgr = entry->private_data;
1186 unsigned long maxsize;
1187 1131
1188 if (pos > MIXART_BA1_SIZE)
1189 return 0;
1190 maxsize = MIXART_BA1_SIZE - pos;
1191 if (count > maxsize)
1192 count = maxsize;
1193 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ 1132 count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
1194 if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count)) 1133 if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
1195 return -EFAULT; 1134 return -EFAULT;
@@ -1198,12 +1137,10 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
1198 1137
1199static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = { 1138static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = {
1200 .read = snd_mixart_BA0_read, 1139 .read = snd_mixart_BA0_read,
1201 .llseek = snd_mixart_BA0_llseek
1202}; 1140};
1203 1141
1204static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = { 1142static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = {
1205 .read = snd_mixart_BA1_read, 1143 .read = snd_mixart_BA1_read,
1206 .llseek = snd_mixart_BA1_llseek
1207}; 1144};
1208 1145
1209 1146
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index edaa729126bb..df110df52a8b 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -142,12 +142,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
142 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 142 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
143 link->io.NumPorts1 = 16; 143 link->io.NumPorts1 = 16;
144 144
145 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; 145 link->conf.Attributes = CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ;
146 /* FIXME: This driver should be updated to allow for dynamic IRQ sharing */
147 /* link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; */
148
149 link->irq.Handler = pdacf_interrupt;
150 link->conf.Attributes = CONF_ENABLE_IRQ;
151 link->conf.IntType = INT_MEMORY_AND_IO; 146 link->conf.IntType = INT_MEMORY_AND_IO;
152 link->conf.ConfigIndex = 1; 147 link->conf.ConfigIndex = 1;
153 link->conf.Present = PRESENT_OPTION; 148 link->conf.Present = PRESENT_OPTION;
@@ -228,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
228 if (ret) 223 if (ret)
229 goto failed; 224 goto failed;
230 225
231 ret = pcmcia_request_irq(link, &link->irq); 226 ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
232 if (ret) 227 if (ret)
233 goto failed; 228 goto failed;
234 229
@@ -236,10 +231,9 @@ static int pdacf_config(struct pcmcia_device *link)
236 if (ret) 231 if (ret)
237 goto failed; 232 goto failed;
238 233
239 if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) 234 if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq) < 0)
240 goto failed; 235 goto failed;
241 236
242 link->dev_node = &pdacf->node;
243 return 0; 237 return 0;
244 238
245failed: 239failed:
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index b0601838112d..a0a7ec64222a 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -117,7 +117,6 @@ struct snd_pdacf {
117 117
118 /* pcmcia stuff */ 118 /* pcmcia stuff */
119 struct pcmcia_device *p_dev; 119 struct pcmcia_device *p_dev;
120 dev_node_t node;
121}; 120};
122 121
123static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val) 122static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val)
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index cfd1438bcc64..624b47a85f0a 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -162,10 +162,6 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
162 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 162 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
163 link->io.NumPorts1 = 16; 163 link->io.NumPorts1 = 16;
164 164
165 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
166
167 link->irq.Handler = &snd_vx_irq_handler;
168
169 link->conf.Attributes = CONF_ENABLE_IRQ; 165 link->conf.Attributes = CONF_ENABLE_IRQ;
170 link->conf.IntType = INT_MEMORY_AND_IO; 166 link->conf.IntType = INT_MEMORY_AND_IO;
171 link->conf.ConfigIndex = 1; 167 link->conf.ConfigIndex = 1;
@@ -215,7 +211,6 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
215static int vxpocket_config(struct pcmcia_device *link) 211static int vxpocket_config(struct pcmcia_device *link)
216{ 212{
217 struct vx_core *chip = link->priv; 213 struct vx_core *chip = link->priv;
218 struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
219 int ret; 214 int ret;
220 215
221 snd_printdd(KERN_DEBUG "vxpocket_config called\n"); 216 snd_printdd(KERN_DEBUG "vxpocket_config called\n");
@@ -235,7 +230,7 @@ static int vxpocket_config(struct pcmcia_device *link)
235 if (ret) 230 if (ret)
236 goto failed; 231 goto failed;
237 232
238 ret = pcmcia_request_irq(link, &link->irq); 233 ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler);
239 if (ret) 234 if (ret)
240 goto failed; 235 goto failed;
241 236
@@ -246,10 +241,9 @@ static int vxpocket_config(struct pcmcia_device *link)
246 chip->dev = &link->dev; 241 chip->dev = &link->dev;
247 snd_card_set_dev(chip->card, chip->dev); 242 snd_card_set_dev(chip->card, chip->dev);
248 243
249 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) 244 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq) < 0)
250 goto failed; 245 goto failed;
251 246
252 link->dev_node = &vxp->node;
253 return 0; 247 return 0;
254 248
255failed: 249failed:
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h
index 27ea002294c0..ea4df16a28ef 100644
--- a/sound/pcmcia/vx/vxpocket.h
+++ b/sound/pcmcia/vx/vxpocket.h
@@ -43,7 +43,6 @@ struct snd_vxpocket {
43 43
44 /* pcmcia stuff */ 44 /* pcmcia stuff */
45 struct pcmcia_device *p_dev; 45 struct pcmcia_device *p_dev;
46 dev_node_t node;
47}; 46};
48 47
49extern struct snd_vx_ops snd_vxpocket_ops; 48extern struct snd_vx_ops snd_vxpocket_ops;
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 789f44f4ac78..20afdf9772ee 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -30,6 +30,7 @@
30#include <linux/kmod.h> 30#include <linux/kmod.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/interrupt.h> 32#include <linux/interrupt.h>
33#include <linux/string.h>
33#include <sound/core.h> 34#include <sound/core.h>
34#include <asm/io.h> 35#include <asm/io.h>
35#include <asm/irq.h> 36#include <asm/irq.h>
@@ -46,6 +47,8 @@
46#define DBG(fmt...) 47#define DBG(fmt...)
47#endif 48#endif
48 49
50#define IS_G4DA (of_machine_is_compatible("PowerMac3,4"))
51
49/* i2c address for tumbler */ 52/* i2c address for tumbler */
50#define TAS_I2C_ADDR 0x34 53#define TAS_I2C_ADDR 0x34
51 54
@@ -243,6 +246,7 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix)
243 snd_printk(KERN_ERR "failed to set volume \n"); 246 snd_printk(KERN_ERR "failed to set volume \n");
244 return -EINVAL; 247 return -EINVAL;
245 } 248 }
249 DBG("(I) succeeded to set volume (%u, %u)\n", left_vol, right_vol);
246 return 0; 250 return 0;
247} 251}
248 252
@@ -353,6 +357,7 @@ static int tumbler_set_drc(struct pmac_tumbler *mix)
353 snd_printk(KERN_ERR "failed to set DRC\n"); 357 snd_printk(KERN_ERR "failed to set DRC\n");
354 return -EINVAL; 358 return -EINVAL;
355 } 359 }
360 DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);
356 return 0; 361 return 0;
357} 362}
358 363
@@ -389,6 +394,7 @@ static int snapper_set_drc(struct pmac_tumbler *mix)
389 snd_printk(KERN_ERR "failed to set DRC\n"); 394 snd_printk(KERN_ERR "failed to set DRC\n");
390 return -EINVAL; 395 return -EINVAL;
391 } 396 }
397 DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]);
392 return 0; 398 return 0;
393} 399}
394 400
@@ -1134,7 +1140,8 @@ static long tumbler_find_device(const char *device, const char *platform,
1134 gp->inactive_val = (*base) ? 0x4 : 0x5; 1140 gp->inactive_val = (*base) ? 0x4 : 0x5;
1135 } else { 1141 } else {
1136 const u32 *prop = NULL; 1142 const u32 *prop = NULL;
1137 gp->active_state = 0; 1143 gp->active_state = IS_G4DA
1144 && !strncmp(device, "keywest-gpio1", 13);
1138 gp->active_val = 0x4; 1145 gp->active_val = 0x4;
1139 gp->inactive_val = 0x5; 1146 gp->inactive_val = 0x5;
1140 /* Here are some crude hacks to extract the GPIO polarity and 1147 /* Here are some crude hacks to extract the GPIO polarity and
@@ -1312,6 +1319,9 @@ static int __devinit tumbler_init(struct snd_pmac *chip)
1312 if (irq <= NO_IRQ) 1319 if (irq <= NO_IRQ)
1313 irq = tumbler_find_device("line-output-detect", 1320 irq = tumbler_find_device("line-output-detect",
1314 NULL, &mix->line_detect, 1); 1321 NULL, &mix->line_detect, 1);
1322 if (IS_G4DA && irq <= NO_IRQ)
1323 irq = tumbler_find_device("keywest-gpio16",
1324 NULL, &mix->line_detect, 1);
1315 mix->lineout_irq = irq; 1325 mix->lineout_irq = irq;
1316 1326
1317 tumbler_reset_audio(chip); 1327 tumbler_reset_audio(chip);
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 3e6628c8e665..f6b3cc04b34b 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -415,9 +415,12 @@ static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
415} 415}
416 416
417#ifdef CONFIG_PM 417#ifdef CONFIG_PM
418static int atmel_pcm_suspend(struct snd_soc_dai *dai) 418static int atmel_pcm_suspend(struct snd_soc_dai_link *dai_link)
419{ 419{
420 struct snd_pcm_runtime *runtime = dai->runtime; 420 struct snd_pcm *pcm = dai_link->pcm;
421 struct snd_pcm_str *stream = &pcm->streams[0];
422 struct snd_pcm_substream *substream = stream->substream;
423 struct snd_pcm_runtime *runtime = substream->runtime;
421 struct atmel_runtime_data *prtd; 424 struct atmel_runtime_data *prtd;
422 struct atmel_pcm_dma_params *params; 425 struct atmel_pcm_dma_params *params;
423 426
@@ -439,9 +442,12 @@ static int atmel_pcm_suspend(struct snd_soc_dai *dai)
439 return 0; 442 return 0;
440} 443}
441 444
442static int atmel_pcm_resume(struct snd_soc_dai *dai) 445static int atmel_pcm_resume(struct snd_soc_dai_link *dai_link)
443{ 446{
444 struct snd_pcm_runtime *runtime = dai->runtime; 447 struct snd_pcm *pcm = dai_link->pcm;
448 struct snd_pcm_str *stream = &pcm->streams[0];
449 struct snd_pcm_substream *substream = stream->substream;
450 struct snd_pcm_runtime *runtime = substream->runtime;
445 struct atmel_runtime_data *prtd; 451 struct atmel_runtime_data *prtd;
446 struct atmel_pcm_dma_params *params; 452 struct atmel_pcm_dma_params *params;
447 453
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 97f1a251e446..8ef25025f3dc 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -49,13 +49,14 @@ config SND_BF5XX_SOC_AD1836
49 help 49 help
50 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT. 50 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
51 51
52config SND_BF5XX_SOC_AD1938 52config SND_BF5XX_SOC_AD193X
53 tristate "SoC AD1938 Audio support for Blackfin" 53 tristate "SoC AD193X Audio support for Blackfin"
54 depends on SND_BF5XX_TDM 54 depends on SND_BF5XX_TDM
55 select SND_BF5XX_SOC_TDM 55 select SND_BF5XX_SOC_TDM
56 select SND_SOC_AD1938 56 select SND_SOC_AD193X
57 help 57 help
58 Say Y if you want to add support for AD1938 codec on Blackfin. 58 Say Y if you want to add support for AD193X codec on Blackfin.
59 This driver supports AD1936, AD1937, AD1938 and AD1939.
59 60
60config SND_BF5XX_AC97 61config SND_BF5XX_AC97
61 tristate "SoC AC97 Audio for the ADI BF5xx chip" 62 tristate "SoC AC97 Audio for the ADI BF5xx chip"
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 87e30423912f..49af3f32aec8 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -20,10 +20,10 @@ snd-ad1836-objs := bf5xx-ad1836.o
20snd-ad1980-objs := bf5xx-ad1980.o 20snd-ad1980-objs := bf5xx-ad1980.o
21snd-ssm2602-objs := bf5xx-ssm2602.o 21snd-ssm2602-objs := bf5xx-ssm2602.o
22snd-ad73311-objs := bf5xx-ad73311.o 22snd-ad73311-objs := bf5xx-ad73311.o
23snd-ad1938-objs := bf5xx-ad1938.o 23snd-ad193x-objs := bf5xx-ad193x.o
24 24
25obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o 25obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o
26obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o 26obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
27obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o 27obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
28obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o 28obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
29obj-$(CONFIG_SND_BF5XX_SOC_AD1938) += snd-ad1938.o 29obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o
diff --git a/sound/soc/blackfin/bf5xx-ad1938.c b/sound/soc/blackfin/bf5xx-ad193x.c
index 2ef1e5013b8c..b8c9060cfd8e 100644
--- a/sound/soc/blackfin/bf5xx-ad1938.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * File: sound/soc/blackfin/bf5xx-ad1938.c 2 * File: sound/soc/blackfin/bf5xx-ad193x.c
3 * Author: Barry Song <Barry.Song@analog.com> 3 * Author: Barry Song <Barry.Song@analog.com>
4 * 4 *
5 * Created: Thur June 4 2009 5 * Created: Thur June 4 2009
6 * Description: Board driver for ad1938 sound chip 6 * Description: Board driver for ad193x sound chip
7 * 7 *
8 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 8 * Bugs: Enter bugs at http://blackfin.uclinux.org/
9 * 9 *
@@ -38,15 +38,15 @@
38#include <asm/dma.h> 38#include <asm/dma.h>
39#include <asm/portmux.h> 39#include <asm/portmux.h>
40 40
41#include "../codecs/ad1938.h" 41#include "../codecs/ad193x.h"
42#include "bf5xx-sport.h" 42#include "bf5xx-sport.h"
43 43
44#include "bf5xx-tdm-pcm.h" 44#include "bf5xx-tdm-pcm.h"
45#include "bf5xx-tdm.h" 45#include "bf5xx-tdm.h"
46 46
47static struct snd_soc_card bf5xx_ad1938; 47static struct snd_soc_card bf5xx_ad193x;
48 48
49static int bf5xx_ad1938_startup(struct snd_pcm_substream *substream) 49static int bf5xx_ad193x_startup(struct snd_pcm_substream *substream)
50{ 50{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data; 51 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 52 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -55,7 +55,7 @@ static int bf5xx_ad1938_startup(struct snd_pcm_substream *substream)
55 return 0; 55 return 0;
56} 56}
57 57
58static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream, 58static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
59 struct snd_pcm_hw_params *params) 59 struct snd_pcm_hw_params *params)
60{ 60{
61 struct snd_soc_pcm_runtime *rtd = substream->private_data; 61 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -89,61 +89,61 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
89 return 0; 89 return 0;
90} 90}
91 91
92static struct snd_soc_ops bf5xx_ad1938_ops = { 92static struct snd_soc_ops bf5xx_ad193x_ops = {
93 .startup = bf5xx_ad1938_startup, 93 .startup = bf5xx_ad193x_startup,
94 .hw_params = bf5xx_ad1938_hw_params, 94 .hw_params = bf5xx_ad193x_hw_params,
95}; 95};
96 96
97static struct snd_soc_dai_link bf5xx_ad1938_dai = { 97static struct snd_soc_dai_link bf5xx_ad193x_dai = {
98 .name = "ad1938", 98 .name = "ad193x",
99 .stream_name = "AD1938", 99 .stream_name = "AD193X",
100 .cpu_dai = &bf5xx_tdm_dai, 100 .cpu_dai = &bf5xx_tdm_dai,
101 .codec_dai = &ad1938_dai, 101 .codec_dai = &ad193x_dai,
102 .ops = &bf5xx_ad1938_ops, 102 .ops = &bf5xx_ad193x_ops,
103}; 103};
104 104
105static struct snd_soc_card bf5xx_ad1938 = { 105static struct snd_soc_card bf5xx_ad193x = {
106 .name = "bf5xx_ad1938", 106 .name = "bf5xx_ad193x",
107 .platform = &bf5xx_tdm_soc_platform, 107 .platform = &bf5xx_tdm_soc_platform,
108 .dai_link = &bf5xx_ad1938_dai, 108 .dai_link = &bf5xx_ad193x_dai,
109 .num_links = 1, 109 .num_links = 1,
110}; 110};
111 111
112static struct snd_soc_device bf5xx_ad1938_snd_devdata = { 112static struct snd_soc_device bf5xx_ad193x_snd_devdata = {
113 .card = &bf5xx_ad1938, 113 .card = &bf5xx_ad193x,
114 .codec_dev = &soc_codec_dev_ad1938, 114 .codec_dev = &soc_codec_dev_ad193x,
115}; 115};
116 116
117static struct platform_device *bfxx_ad1938_snd_device; 117static struct platform_device *bfxx_ad193x_snd_device;
118 118
119static int __init bf5xx_ad1938_init(void) 119static int __init bf5xx_ad193x_init(void)
120{ 120{
121 int ret; 121 int ret;
122 122
123 bfxx_ad1938_snd_device = platform_device_alloc("soc-audio", -1); 123 bfxx_ad193x_snd_device = platform_device_alloc("soc-audio", -1);
124 if (!bfxx_ad1938_snd_device) 124 if (!bfxx_ad193x_snd_device)
125 return -ENOMEM; 125 return -ENOMEM;
126 126
127 platform_set_drvdata(bfxx_ad1938_snd_device, &bf5xx_ad1938_snd_devdata); 127 platform_set_drvdata(bfxx_ad193x_snd_device, &bf5xx_ad193x_snd_devdata);
128 bf5xx_ad1938_snd_devdata.dev = &bfxx_ad1938_snd_device->dev; 128 bf5xx_ad193x_snd_devdata.dev = &bfxx_ad193x_snd_device->dev;
129 ret = platform_device_add(bfxx_ad1938_snd_device); 129 ret = platform_device_add(bfxx_ad193x_snd_device);
130 130
131 if (ret) 131 if (ret)
132 platform_device_put(bfxx_ad1938_snd_device); 132 platform_device_put(bfxx_ad193x_snd_device);
133 133
134 return ret; 134 return ret;
135} 135}
136 136
137static void __exit bf5xx_ad1938_exit(void) 137static void __exit bf5xx_ad193x_exit(void)
138{ 138{
139 platform_device_unregister(bfxx_ad1938_snd_device); 139 platform_device_unregister(bfxx_ad193x_snd_device);
140} 140}
141 141
142module_init(bf5xx_ad1938_init); 142module_init(bf5xx_ad193x_init);
143module_exit(bf5xx_ad1938_exit); 143module_exit(bf5xx_ad193x_exit);
144 144
145/* Module information */ 145/* Module information */
146MODULE_AUTHOR("Barry Song"); 146MODULE_AUTHOR("Barry Song");
147MODULE_DESCRIPTION("ALSA SoC AD1938 board driver"); 147MODULE_DESCRIPTION("ALSA SoC AD193X board driver");
148MODULE_LICENSE("GPL"); 148MODULE_LICENSE("GPL");
149 149
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index 2e63dea73e9c..a86e8cc0b2d3 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -34,33 +34,7 @@
34#include <linux/wait.h> 34#include <linux/wait.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
36#include <asm/dma.h> 36#include <asm/dma.h>
37 37#include <asm/bfin_sport.h>
38struct sport_register {
39 u16 tcr1; u16 reserved0;
40 u16 tcr2; u16 reserved1;
41 u16 tclkdiv; u16 reserved2;
42 u16 tfsdiv; u16 reserved3;
43 u32 tx;
44 u32 reserved_l0;
45 u32 rx;
46 u32 reserved_l1;
47 u16 rcr1; u16 reserved4;
48 u16 rcr2; u16 reserved5;
49 u16 rclkdiv; u16 reserved6;
50 u16 rfsdiv; u16 reserved7;
51 u16 stat; u16 reserved8;
52 u16 chnl; u16 reserved9;
53 u16 mcmc1; u16 reserved10;
54 u16 mcmc2; u16 reserved11;
55 u32 mtcs0;
56 u32 mtcs1;
57 u32 mtcs2;
58 u32 mtcs3;
59 u32 mrcs0;
60 u32 mrcs1;
61 u32 mrcs2;
62 u32 mrcs3;
63};
64 38
65#define DESC_ELEMENT_COUNT 9 39#define DESC_ELEMENT_COUNT 9
66 40
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1743d565e996..31ac5538fe7e 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -13,7 +13,7 @@ config SND_SOC_ALL_CODECS
13 select SND_SOC_L3 13 select SND_SOC_L3
14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
15 select SND_SOC_AD1836 if SPI_MASTER 15 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD1938 if SPI_MASTER 16 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
18 select SND_SOC_ADS117X 18 select SND_SOC_ADS117X
19 select SND_SOC_AD73311 if I2C 19 select SND_SOC_AD73311 if I2C
@@ -21,6 +21,7 @@ config SND_SOC_ALL_CODECS
21 select SND_SOC_AK4535 if I2C 21 select SND_SOC_AK4535 if I2C
22 select SND_SOC_AK4642 if I2C 22 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C 23 select SND_SOC_AK4671 if I2C
24 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
24 select SND_SOC_CS4270 if I2C 25 select SND_SOC_CS4270 if I2C
25 select SND_SOC_MAX9877 if I2C 26 select SND_SOC_MAX9877 if I2C
26 select SND_SOC_DA7210 if I2C 27 select SND_SOC_DA7210 if I2C
@@ -34,6 +35,7 @@ config SND_SOC_ALL_CODECS
34 select SND_SOC_TPA6130A2 if I2C 35 select SND_SOC_TPA6130A2 if I2C
35 select SND_SOC_TLV320DAC33 if I2C 36 select SND_SOC_TLV320DAC33 if I2C
36 select SND_SOC_TWL4030 if TWL4030_CORE 37 select SND_SOC_TWL4030 if TWL4030_CORE
38 select SND_SOC_TWL6040 if TWL4030_CORE
37 select SND_SOC_UDA134X 39 select SND_SOC_UDA134X
38 select SND_SOC_UDA1380 if I2C 40 select SND_SOC_UDA1380 if I2C
39 select SND_SOC_WM2000 if I2C 41 select SND_SOC_WM2000 if I2C
@@ -64,6 +66,7 @@ config SND_SOC_ALL_CODECS
64 select SND_SOC_WM8993 if I2C 66 select SND_SOC_WM8993 if I2C
65 select SND_SOC_WM8994 if MFD_WM8994 67 select SND_SOC_WM8994 if MFD_WM8994
66 select SND_SOC_WM9081 if I2C 68 select SND_SOC_WM9081 if I2C
69 select SND_SOC_WM9090 if I2C
67 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 70 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
68 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 71 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
69 select SND_SOC_WM9713 if SND_SOC_AC97_BUS 72 select SND_SOC_WM9713 if SND_SOC_AC97_BUS
@@ -90,7 +93,7 @@ config SND_SOC_AC97_CODEC
90config SND_SOC_AD1836 93config SND_SOC_AD1836
91 tristate 94 tristate
92 95
93config SND_SOC_AD1938 96config SND_SOC_AD193X
94 tristate 97 tristate
95 98
96config SND_SOC_AD1980 99config SND_SOC_AD1980
@@ -114,6 +117,9 @@ config SND_SOC_AK4642
114config SND_SOC_AK4671 117config SND_SOC_AK4671
115 tristate 118 tristate
116 119
120config SND_SOC_CQ0093VC
121 tristate
122
117# Cirrus Logic CS4270 Codec 123# Cirrus Logic CS4270 Codec
118config SND_SOC_CS4270 124config SND_SOC_CS4270
119 tristate 125 tristate
@@ -164,6 +170,9 @@ config SND_SOC_TWL4030
164 select TWL4030_CODEC 170 select TWL4030_CODEC
165 tristate 171 tristate
166 172
173config SND_SOC_TWL6040
174 tristate
175
167config SND_SOC_UDA134X 176config SND_SOC_UDA134X
168 tristate 177 tristate
169 178
@@ -269,3 +278,6 @@ config SND_SOC_TPA6130A2
269 278
270config SND_SOC_WM2000 279config SND_SOC_WM2000
271 tristate 280 tristate
281
282config SND_SOC_WM9090
283 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index dd5ce6df6292..91429eab0707 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,6 +1,6 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1836-objs := ad1836.o 2snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad1938-objs := ad1938.o 3snd-soc-ad193x-objs := ad193x.o
4snd-soc-ad1980-objs := ad1980.o 4snd-soc-ad1980-objs := ad1980.o
5snd-soc-ad73311-objs := ad73311.o 5snd-soc-ad73311-objs := ad73311.o
6snd-soc-ads117x-objs := ads117x.o 6snd-soc-ads117x-objs := ads117x.o
@@ -8,6 +8,7 @@ snd-soc-ak4104-objs := ak4104.o
8snd-soc-ak4535-objs := ak4535.o 8snd-soc-ak4535-objs := ak4535.o
9snd-soc-ak4642-objs := ak4642.o 9snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o 10snd-soc-ak4671-objs := ak4671.o
11snd-soc-cq93vc-objs := cq93vc.o
11snd-soc-cs4270-objs := cs4270.o 12snd-soc-cs4270-objs := cs4270.o
12snd-soc-cx20442-objs := cx20442.o 13snd-soc-cx20442-objs := cx20442.o
13snd-soc-da7210-objs := da7210.o 14snd-soc-da7210-objs := da7210.o
@@ -21,6 +22,7 @@ snd-soc-tlv320aic26-objs := tlv320aic26.o
21snd-soc-tlv320aic3x-objs := tlv320aic3x.o 22snd-soc-tlv320aic3x-objs := tlv320aic3x.o
22snd-soc-tlv320dac33-objs := tlv320dac33.o 23snd-soc-tlv320dac33-objs := tlv320dac33.o
23snd-soc-twl4030-objs := twl4030.o 24snd-soc-twl4030-objs := twl4030.o
25snd-soc-twl6040-objs := twl6040.o
24snd-soc-uda134x-objs := uda134x.o 26snd-soc-uda134x-objs := uda134x.o
25snd-soc-uda1380-objs := uda1380.o 27snd-soc-uda1380-objs := uda1380.o
26snd-soc-wm8350-objs := wm8350.o 28snd-soc-wm8350-objs := wm8350.o
@@ -59,10 +61,11 @@ snd-soc-wm-hubs-objs := wm_hubs.o
59snd-soc-max9877-objs := max9877.o 61snd-soc-max9877-objs := max9877.o
60snd-soc-tpa6130a2-objs := tpa6130a2.o 62snd-soc-tpa6130a2-objs := tpa6130a2.o
61snd-soc-wm2000-objs := wm2000.o 63snd-soc-wm2000-objs := wm2000.o
64snd-soc-wm9090-objs := wm9090.o
62 65
63obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 66obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
64obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 67obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
65obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o 68obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
66obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 69obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
67obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 70obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
68obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 71obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
@@ -70,6 +73,7 @@ obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
70obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 73obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
71obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 74obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
72obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 75obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
76obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
73obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 77obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
74obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 78obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
75obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 79obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
@@ -83,6 +87,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
83obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 87obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
84obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o 88obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
85obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 89obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
90obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
86obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 91obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
87obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 92obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
88obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 93obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
@@ -121,3 +126,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
121obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 126obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
122obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 127obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
123obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 128obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
129obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 11b62dee842c..217538423225 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -278,7 +278,7 @@ static int ad1836_register(struct ad1836_priv *ad1836)
278 mutex_init(&codec->mutex); 278 mutex_init(&codec->mutex);
279 INIT_LIST_HEAD(&codec->dapm_widgets); 279 INIT_LIST_HEAD(&codec->dapm_widgets);
280 INIT_LIST_HEAD(&codec->dapm_paths); 280 INIT_LIST_HEAD(&codec->dapm_paths);
281 codec->private_data = ad1836; 281 snd_soc_codec_set_drvdata(codec, ad1836);
282 codec->reg_cache = ad1836->reg_cache; 282 codec->reg_cache = ad1836->reg_cache;
283 codec->reg_cache_size = AD1836_NUM_REGS; 283 codec->reg_cache_size = AD1836_NUM_REGS;
284 codec->name = "AD1836"; 284 codec->name = "AD1836";
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
deleted file mode 100644
index 240cd155b313..000000000000
--- a/sound/soc/codecs/ad1938.c
+++ /dev/null
@@ -1,522 +0,0 @@
1/*
2 * File: sound/soc/codecs/ad1938.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: June 04 2009
6 * Description: Driver for AD1938 sound chip
7 *
8 * Modified:
9 * Copyright 2009 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/device.h>
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/initval.h>
38#include <sound/soc.h>
39#include <sound/tlv.h>
40#include <sound/soc-dapm.h>
41#include <linux/spi/spi.h>
42#include "ad1938.h"
43
44/* codec private data */
45struct ad1938_priv {
46 struct snd_soc_codec codec;
47 u8 reg_cache[AD1938_NUM_REGS];
48};
49
50/* ad1938 register cache & default register settings */
51static const u8 ad1938_reg[AD1938_NUM_REGS] = {
52 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
53};
54
55static struct snd_soc_codec *ad1938_codec;
56struct snd_soc_codec_device soc_codec_dev_ad1938;
57static int ad1938_register(struct ad1938_priv *ad1938);
58static void ad1938_unregister(struct ad1938_priv *ad1938);
59
60/*
61 * AD1938 volume/mute/de-emphasis etc. controls
62 */
63static const char *ad1938_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
64
65static const struct soc_enum ad1938_deemp_enum =
66 SOC_ENUM_SINGLE(AD1938_DAC_CTRL2, 1, 4, ad1938_deemp);
67
68static const struct snd_kcontrol_new ad1938_snd_controls[] = {
69 /* DAC volume control */
70 SOC_DOUBLE_R("DAC1 Volume", AD1938_DAC_L1_VOL,
71 AD1938_DAC_R1_VOL, 0, 0xFF, 1),
72 SOC_DOUBLE_R("DAC2 Volume", AD1938_DAC_L2_VOL,
73 AD1938_DAC_R2_VOL, 0, 0xFF, 1),
74 SOC_DOUBLE_R("DAC3 Volume", AD1938_DAC_L3_VOL,
75 AD1938_DAC_R3_VOL, 0, 0xFF, 1),
76 SOC_DOUBLE_R("DAC4 Volume", AD1938_DAC_L4_VOL,
77 AD1938_DAC_R4_VOL, 0, 0xFF, 1),
78
79 /* ADC switch control */
80 SOC_DOUBLE("ADC1 Switch", AD1938_ADC_CTRL0, AD1938_ADCL1_MUTE,
81 AD1938_ADCR1_MUTE, 1, 1),
82 SOC_DOUBLE("ADC2 Switch", AD1938_ADC_CTRL0, AD1938_ADCL2_MUTE,
83 AD1938_ADCR2_MUTE, 1, 1),
84
85 /* DAC switch control */
86 SOC_DOUBLE("DAC1 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL1_MUTE,
87 AD1938_DACR1_MUTE, 1, 1),
88 SOC_DOUBLE("DAC2 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL2_MUTE,
89 AD1938_DACR2_MUTE, 1, 1),
90 SOC_DOUBLE("DAC3 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL3_MUTE,
91 AD1938_DACR3_MUTE, 1, 1),
92 SOC_DOUBLE("DAC4 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL4_MUTE,
93 AD1938_DACR4_MUTE, 1, 1),
94
95 /* ADC high-pass filter */
96 SOC_SINGLE("ADC High Pass Filter Switch", AD1938_ADC_CTRL0,
97 AD1938_ADC_HIGHPASS_FILTER, 1, 0),
98
99 /* DAC de-emphasis */
100 SOC_ENUM("Playback Deemphasis", ad1938_deemp_enum),
101};
102
103static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
104 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
105 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
106 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD1938_PLL_CLK_CTRL0, 0, 1, NULL, 0),
107 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
108 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
109 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
110 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
111 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
112 SND_SOC_DAPM_INPUT("ADC1IN"),
113 SND_SOC_DAPM_INPUT("ADC2IN"),
114};
115
116static const struct snd_soc_dapm_route audio_paths[] = {
117 { "DAC", NULL, "PLL_PWR" },
118 { "ADC", NULL, "PLL_PWR" },
119 { "DAC", NULL, "ADC_PWR" },
120 { "ADC", NULL, "ADC_PWR" },
121 { "DAC1OUT", "DAC1 Switch", "DAC" },
122 { "DAC2OUT", "DAC2 Switch", "DAC" },
123 { "DAC3OUT", "DAC3 Switch", "DAC" },
124 { "DAC4OUT", "DAC4 Switch", "DAC" },
125 { "ADC", "ADC1 Switch", "ADC1IN" },
126 { "ADC", "ADC2 Switch", "ADC2IN" },
127};
128
129/*
130 * DAI ops entries
131 */
132
133static int ad1938_mute(struct snd_soc_dai *dai, int mute)
134{
135 struct snd_soc_codec *codec = dai->codec;
136 int reg;
137
138 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
139 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
140 (~AD1938_DAC_MASTER_MUTE);
141 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
142
143 return 0;
144}
145
146static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
147 unsigned int rx_mask, int slots, int width)
148{
149 struct snd_soc_codec *codec = dai->codec;
150 int dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
151 int adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
152
153 dac_reg &= ~AD1938_DAC_CHAN_MASK;
154 adc_reg &= ~AD1938_ADC_CHAN_MASK;
155
156 switch (slots) {
157 case 2:
158 dac_reg |= AD1938_DAC_2_CHANNELS << AD1938_DAC_CHAN_SHFT;
159 adc_reg |= AD1938_ADC_2_CHANNELS << AD1938_ADC_CHAN_SHFT;
160 break;
161 case 4:
162 dac_reg |= AD1938_DAC_4_CHANNELS << AD1938_DAC_CHAN_SHFT;
163 adc_reg |= AD1938_ADC_4_CHANNELS << AD1938_ADC_CHAN_SHFT;
164 break;
165 case 8:
166 dac_reg |= AD1938_DAC_8_CHANNELS << AD1938_DAC_CHAN_SHFT;
167 adc_reg |= AD1938_ADC_8_CHANNELS << AD1938_ADC_CHAN_SHFT;
168 break;
169 case 16:
170 dac_reg |= AD1938_DAC_16_CHANNELS << AD1938_DAC_CHAN_SHFT;
171 adc_reg |= AD1938_ADC_16_CHANNELS << AD1938_ADC_CHAN_SHFT;
172 break;
173 default:
174 return -EINVAL;
175 }
176
177 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
178 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
179
180 return 0;
181}
182
183static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
184 unsigned int fmt)
185{
186 struct snd_soc_codec *codec = codec_dai->codec;
187 int adc_reg, dac_reg;
188
189 adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
190 dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
191
192 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
193 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
194 */
195 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
196 case SND_SOC_DAIFMT_I2S:
197 adc_reg &= ~AD1938_ADC_SERFMT_MASK;
198 adc_reg |= AD1938_ADC_SERFMT_TDM;
199 break;
200 case SND_SOC_DAIFMT_DSP_A:
201 adc_reg &= ~AD1938_ADC_SERFMT_MASK;
202 adc_reg |= AD1938_ADC_SERFMT_AUX;
203 break;
204 default:
205 return -EINVAL;
206 }
207
208 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
209 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
210 adc_reg &= ~AD1938_ADC_LEFT_HIGH;
211 adc_reg &= ~AD1938_ADC_BCLK_INV;
212 dac_reg &= ~AD1938_DAC_LEFT_HIGH;
213 dac_reg &= ~AD1938_DAC_BCLK_INV;
214 break;
215 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
216 adc_reg |= AD1938_ADC_LEFT_HIGH;
217 adc_reg &= ~AD1938_ADC_BCLK_INV;
218 dac_reg |= AD1938_DAC_LEFT_HIGH;
219 dac_reg &= ~AD1938_DAC_BCLK_INV;
220 break;
221 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
222 adc_reg &= ~AD1938_ADC_LEFT_HIGH;
223 adc_reg |= AD1938_ADC_BCLK_INV;
224 dac_reg &= ~AD1938_DAC_LEFT_HIGH;
225 dac_reg |= AD1938_DAC_BCLK_INV;
226 break;
227
228 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
229 adc_reg |= AD1938_ADC_LEFT_HIGH;
230 adc_reg |= AD1938_ADC_BCLK_INV;
231 dac_reg |= AD1938_DAC_LEFT_HIGH;
232 dac_reg |= AD1938_DAC_BCLK_INV;
233 break;
234 default:
235 return -EINVAL;
236 }
237
238 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
239 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
240 adc_reg |= AD1938_ADC_LCR_MASTER;
241 adc_reg |= AD1938_ADC_BCLK_MASTER;
242 dac_reg |= AD1938_DAC_LCR_MASTER;
243 dac_reg |= AD1938_DAC_BCLK_MASTER;
244 break;
245 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
246 adc_reg |= AD1938_ADC_LCR_MASTER;
247 adc_reg &= ~AD1938_ADC_BCLK_MASTER;
248 dac_reg |= AD1938_DAC_LCR_MASTER;
249 dac_reg &= ~AD1938_DAC_BCLK_MASTER;
250 break;
251 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
252 adc_reg &= ~AD1938_ADC_LCR_MASTER;
253 adc_reg |= AD1938_ADC_BCLK_MASTER;
254 dac_reg &= ~AD1938_DAC_LCR_MASTER;
255 dac_reg |= AD1938_DAC_BCLK_MASTER;
256 break;
257 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
258 adc_reg &= ~AD1938_ADC_LCR_MASTER;
259 adc_reg &= ~AD1938_ADC_BCLK_MASTER;
260 dac_reg &= ~AD1938_DAC_LCR_MASTER;
261 dac_reg &= ~AD1938_DAC_BCLK_MASTER;
262 break;
263 default:
264 return -EINVAL;
265 }
266
267 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
268 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
269
270 return 0;
271}
272
273static int ad1938_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
276{
277 int word_len = 0, reg = 0;
278
279 struct snd_soc_pcm_runtime *rtd = substream->private_data;
280 struct snd_soc_device *socdev = rtd->socdev;
281 struct snd_soc_codec *codec = socdev->card->codec;
282
283 /* bit size */
284 switch (params_format(params)) {
285 case SNDRV_PCM_FORMAT_S16_LE:
286 word_len = 3;
287 break;
288 case SNDRV_PCM_FORMAT_S20_3LE:
289 word_len = 1;
290 break;
291 case SNDRV_PCM_FORMAT_S24_LE:
292 case SNDRV_PCM_FORMAT_S32_LE:
293 word_len = 0;
294 break;
295 }
296
297 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
298 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
299 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
300
301 reg = snd_soc_read(codec, AD1938_ADC_CTRL1);
302 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
303 snd_soc_write(codec, AD1938_ADC_CTRL1, reg);
304
305 return 0;
306}
307
308static int __devinit ad1938_spi_probe(struct spi_device *spi)
309{
310 struct snd_soc_codec *codec;
311 struct ad1938_priv *ad1938;
312
313 ad1938 = kzalloc(sizeof(struct ad1938_priv), GFP_KERNEL);
314 if (ad1938 == NULL)
315 return -ENOMEM;
316
317 codec = &ad1938->codec;
318 codec->control_data = spi;
319 codec->dev = &spi->dev;
320
321 dev_set_drvdata(&spi->dev, ad1938);
322
323 return ad1938_register(ad1938);
324}
325
326static int __devexit ad1938_spi_remove(struct spi_device *spi)
327{
328 struct ad1938_priv *ad1938 = dev_get_drvdata(&spi->dev);
329
330 ad1938_unregister(ad1938);
331 return 0;
332}
333
334static struct spi_driver ad1938_spi_driver = {
335 .driver = {
336 .name = "ad1938",
337 .owner = THIS_MODULE,
338 },
339 .probe = ad1938_spi_probe,
340 .remove = __devexit_p(ad1938_spi_remove),
341};
342
343static struct snd_soc_dai_ops ad1938_dai_ops = {
344 .hw_params = ad1938_hw_params,
345 .digital_mute = ad1938_mute,
346 .set_tdm_slot = ad1938_set_tdm_slot,
347 .set_fmt = ad1938_set_dai_fmt,
348};
349
350/* codec DAI instance */
351struct snd_soc_dai ad1938_dai = {
352 .name = "AD1938",
353 .playback = {
354 .stream_name = "Playback",
355 .channels_min = 2,
356 .channels_max = 8,
357 .rates = SNDRV_PCM_RATE_48000,
358 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
359 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
360 },
361 .capture = {
362 .stream_name = "Capture",
363 .channels_min = 2,
364 .channels_max = 4,
365 .rates = SNDRV_PCM_RATE_48000,
366 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
367 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
368 },
369 .ops = &ad1938_dai_ops,
370};
371EXPORT_SYMBOL_GPL(ad1938_dai);
372
373static int ad1938_register(struct ad1938_priv *ad1938)
374{
375 int ret;
376 struct snd_soc_codec *codec = &ad1938->codec;
377
378 if (ad1938_codec) {
379 dev_err(codec->dev, "Another ad1938 is registered\n");
380 return -EINVAL;
381 }
382
383 mutex_init(&codec->mutex);
384 INIT_LIST_HEAD(&codec->dapm_widgets);
385 INIT_LIST_HEAD(&codec->dapm_paths);
386 codec->private_data = ad1938;
387 codec->reg_cache = ad1938->reg_cache;
388 codec->reg_cache_size = AD1938_NUM_REGS;
389 codec->name = "AD1938";
390 codec->owner = THIS_MODULE;
391 codec->dai = &ad1938_dai;
392 codec->num_dai = 1;
393 INIT_LIST_HEAD(&codec->dapm_widgets);
394 INIT_LIST_HEAD(&codec->dapm_paths);
395
396 ad1938_dai.dev = codec->dev;
397 ad1938_codec = codec;
398
399 memcpy(codec->reg_cache, ad1938_reg, AD1938_NUM_REGS);
400
401 ret = snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_SPI);
402 if (ret < 0) {
403 dev_err(codec->dev, "failed to set cache I/O: %d\n",
404 ret);
405 kfree(ad1938);
406 return ret;
407 }
408
409 /* default setting for ad1938 */
410
411 /* unmute dac channels */
412 snd_soc_write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
413 /* de-emphasis: 48kHz, powedown dac */
414 snd_soc_write(codec, AD1938_DAC_CTRL2, 0x1A);
415 /* powerdown dac, dac in tdm mode */
416 snd_soc_write(codec, AD1938_DAC_CTRL0, 0x41);
417 /* high-pass filter enable */
418 snd_soc_write(codec, AD1938_ADC_CTRL0, 0x3);
419 /* sata delay=1, adc aux mode */
420 snd_soc_write(codec, AD1938_ADC_CTRL1, 0x43);
421 /* pll input: mclki/xi */
422 snd_soc_write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
423 snd_soc_write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
424
425 ret = snd_soc_register_codec(codec);
426 if (ret != 0) {
427 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
428 kfree(ad1938);
429 return ret;
430 }
431
432 ret = snd_soc_register_dai(&ad1938_dai);
433 if (ret != 0) {
434 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
435 snd_soc_unregister_codec(codec);
436 kfree(ad1938);
437 return ret;
438 }
439
440 return 0;
441}
442
443static void ad1938_unregister(struct ad1938_priv *ad1938)
444{
445 snd_soc_unregister_dai(&ad1938_dai);
446 snd_soc_unregister_codec(&ad1938->codec);
447 kfree(ad1938);
448 ad1938_codec = NULL;
449}
450
451static int ad1938_probe(struct platform_device *pdev)
452{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
454 struct snd_soc_codec *codec;
455 int ret = 0;
456
457 if (ad1938_codec == NULL) {
458 dev_err(&pdev->dev, "Codec device not registered\n");
459 return -ENODEV;
460 }
461
462 socdev->card->codec = ad1938_codec;
463 codec = ad1938_codec;
464
465 /* register pcms */
466 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
467 if (ret < 0) {
468 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
469 goto pcm_err;
470 }
471
472 snd_soc_add_controls(codec, ad1938_snd_controls,
473 ARRAY_SIZE(ad1938_snd_controls));
474 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets,
475 ARRAY_SIZE(ad1938_dapm_widgets));
476 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
477
478
479pcm_err:
480 return ret;
481}
482
483/* power down chip */
484static int ad1938_remove(struct platform_device *pdev)
485{
486 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
487
488 snd_soc_free_pcms(socdev);
489 snd_soc_dapm_free(socdev);
490
491 return 0;
492}
493
494struct snd_soc_codec_device soc_codec_dev_ad1938 = {
495 .probe = ad1938_probe,
496 .remove = ad1938_remove,
497};
498EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
499
500static int __init ad1938_init(void)
501{
502 int ret;
503
504 ret = spi_register_driver(&ad1938_spi_driver);
505 if (ret != 0) {
506 printk(KERN_ERR "Failed to register ad1938 SPI driver: %d\n",
507 ret);
508 }
509
510 return ret;
511}
512module_init(ad1938_init);
513
514static void __exit ad1938_exit(void)
515{
516 spi_unregister_driver(&ad1938_spi_driver);
517}
518module_exit(ad1938_exit);
519
520MODULE_DESCRIPTION("ASoC ad1938 driver");
521MODULE_AUTHOR("Barry Song ");
522MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1938.h b/sound/soc/codecs/ad1938.h
deleted file mode 100644
index fe3c48cd2d5b..000000000000
--- a/sound/soc/codecs/ad1938.h
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * File: sound/soc/codecs/ad1836.h
3 * Based on:
4 * Author: Barry Song <Barry.Song@analog.com>
5 *
6 * Created: May 25, 2009
7 * Description: definitions for AD1938 registers
8 *
9 * Modified:
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#ifndef __AD1938_H__
30#define __AD1938_H__
31
32#define AD1938_PLL_CLK_CTRL0 0
33#define AD1938_PLL_POWERDOWN 0x01
34#define AD1938_PLL_CLK_CTRL1 1
35#define AD1938_DAC_CTRL0 2
36#define AD1938_DAC_POWERDOWN 0x01
37#define AD1938_DAC_SERFMT_MASK 0xC0
38#define AD1938_DAC_SERFMT_STEREO (0 << 6)
39#define AD1938_DAC_SERFMT_TDM (1 << 6)
40#define AD1938_DAC_CTRL1 3
41#define AD1938_DAC_2_CHANNELS 0
42#define AD1938_DAC_4_CHANNELS 1
43#define AD1938_DAC_8_CHANNELS 2
44#define AD1938_DAC_16_CHANNELS 3
45#define AD1938_DAC_CHAN_SHFT 1
46#define AD1938_DAC_CHAN_MASK (3 << AD1938_DAC_CHAN_SHFT)
47#define AD1938_DAC_LCR_MASTER (1 << 4)
48#define AD1938_DAC_BCLK_MASTER (1 << 5)
49#define AD1938_DAC_LEFT_HIGH (1 << 3)
50#define AD1938_DAC_BCLK_INV (1 << 7)
51#define AD1938_DAC_CTRL2 4
52#define AD1938_DAC_WORD_LEN_MASK 0xC
53#define AD1938_DAC_MASTER_MUTE 1
54#define AD1938_DAC_CHNL_MUTE 5
55#define AD1938_DACL1_MUTE 0
56#define AD1938_DACR1_MUTE 1
57#define AD1938_DACL2_MUTE 2
58#define AD1938_DACR2_MUTE 3
59#define AD1938_DACL3_MUTE 4
60#define AD1938_DACR3_MUTE 5
61#define AD1938_DACL4_MUTE 6
62#define AD1938_DACR4_MUTE 7
63#define AD1938_DAC_L1_VOL 6
64#define AD1938_DAC_R1_VOL 7
65#define AD1938_DAC_L2_VOL 8
66#define AD1938_DAC_R2_VOL 9
67#define AD1938_DAC_L3_VOL 10
68#define AD1938_DAC_R3_VOL 11
69#define AD1938_DAC_L4_VOL 12
70#define AD1938_DAC_R4_VOL 13
71#define AD1938_ADC_CTRL0 14
72#define AD1938_ADC_POWERDOWN 0x01
73#define AD1938_ADC_HIGHPASS_FILTER 1
74#define AD1938_ADCL1_MUTE 2
75#define AD1938_ADCR1_MUTE 3
76#define AD1938_ADCL2_MUTE 4
77#define AD1938_ADCR2_MUTE 5
78#define AD1938_ADC_CTRL1 15
79#define AD1938_ADC_SERFMT_MASK 0x60
80#define AD1938_ADC_SERFMT_STEREO (0 << 5)
81#define AD1938_ADC_SERFMT_TDM (1 << 2)
82#define AD1938_ADC_SERFMT_AUX (2 << 5)
83#define AD1938_ADC_WORD_LEN_MASK 0x3
84#define AD1938_ADC_CTRL2 16
85#define AD1938_ADC_2_CHANNELS 0
86#define AD1938_ADC_4_CHANNELS 1
87#define AD1938_ADC_8_CHANNELS 2
88#define AD1938_ADC_16_CHANNELS 3
89#define AD1938_ADC_CHAN_SHFT 4
90#define AD1938_ADC_CHAN_MASK (3 << AD1938_ADC_CHAN_SHFT)
91#define AD1938_ADC_LCR_MASTER (1 << 3)
92#define AD1938_ADC_BCLK_MASTER (1 << 6)
93#define AD1938_ADC_LEFT_HIGH (1 << 2)
94#define AD1938_ADC_BCLK_INV (1 << 1)
95
96#define AD1938_NUM_REGS 17
97
98extern struct snd_soc_dai ad1938_dai;
99extern struct snd_soc_codec_device soc_codec_dev_ad1938;
100#endif
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
new file mode 100644
index 000000000000..c8ca1142b2f4
--- /dev/null
+++ b/sound/soc/codecs/ad193x.c
@@ -0,0 +1,547 @@
1/*
2 * AD193X Audio Codec driver supporting AD1936/7/8/9
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/kernel.h>
12#include <linux/device.h>
13#include <linux/i2c.h>
14#include <linux/spi/spi.h>
15#include <linux/slab.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/initval.h>
20#include <sound/soc.h>
21#include <sound/tlv.h>
22#include <sound/soc-dapm.h>
23#include "ad193x.h"
24
25/* codec private data */
26struct ad193x_priv {
27 struct snd_soc_codec codec;
28 u8 reg_cache[AD193X_NUM_REGS];
29};
30
31/* ad193x register cache & default register settings */
32static const u8 ad193x_reg[AD193X_NUM_REGS] = {
33 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
34};
35
36static struct snd_soc_codec *ad193x_codec;
37struct snd_soc_codec_device soc_codec_dev_ad193x;
38
39/*
40 * AD193X volume/mute/de-emphasis etc. controls
41 */
42static const char *ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
43
44static const struct soc_enum ad193x_deemp_enum =
45 SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp);
46
47static const struct snd_kcontrol_new ad193x_snd_controls[] = {
48 /* DAC volume control */
49 SOC_DOUBLE_R("DAC1 Volume", AD193X_DAC_L1_VOL,
50 AD193X_DAC_R1_VOL, 0, 0xFF, 1),
51 SOC_DOUBLE_R("DAC2 Volume", AD193X_DAC_L2_VOL,
52 AD193X_DAC_R2_VOL, 0, 0xFF, 1),
53 SOC_DOUBLE_R("DAC3 Volume", AD193X_DAC_L3_VOL,
54 AD193X_DAC_R3_VOL, 0, 0xFF, 1),
55 SOC_DOUBLE_R("DAC4 Volume", AD193X_DAC_L4_VOL,
56 AD193X_DAC_R4_VOL, 0, 0xFF, 1),
57
58 /* ADC switch control */
59 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
60 AD193X_ADCR1_MUTE, 1, 1),
61 SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
62 AD193X_ADCR2_MUTE, 1, 1),
63
64 /* DAC switch control */
65 SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE,
66 AD193X_DACR1_MUTE, 1, 1),
67 SOC_DOUBLE("DAC2 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL2_MUTE,
68 AD193X_DACR2_MUTE, 1, 1),
69 SOC_DOUBLE("DAC3 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL3_MUTE,
70 AD193X_DACR3_MUTE, 1, 1),
71 SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE,
72 AD193X_DACR4_MUTE, 1, 1),
73
74 /* ADC high-pass filter */
75 SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0,
76 AD193X_ADC_HIGHPASS_FILTER, 1, 0),
77
78 /* DAC de-emphasis */
79 SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
80};
81
82static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
83 SND_SOC_DAPM_DAC("DAC", "Playback", AD193X_DAC_CTRL0, 0, 1),
84 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
85 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
86 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
87 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
88 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
89 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
90 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
91 SND_SOC_DAPM_INPUT("ADC1IN"),
92 SND_SOC_DAPM_INPUT("ADC2IN"),
93};
94
95static const struct snd_soc_dapm_route audio_paths[] = {
96 { "DAC", NULL, "PLL_PWR" },
97 { "ADC", NULL, "PLL_PWR" },
98 { "DAC", NULL, "ADC_PWR" },
99 { "ADC", NULL, "ADC_PWR" },
100 { "DAC1OUT", "DAC1 Switch", "DAC" },
101 { "DAC2OUT", "DAC2 Switch", "DAC" },
102 { "DAC3OUT", "DAC3 Switch", "DAC" },
103 { "DAC4OUT", "DAC4 Switch", "DAC" },
104 { "ADC", "ADC1 Switch", "ADC1IN" },
105 { "ADC", "ADC2 Switch", "ADC2IN" },
106};
107
108/*
109 * DAI ops entries
110 */
111
112static int ad193x_mute(struct snd_soc_dai *dai, int mute)
113{
114 struct snd_soc_codec *codec = dai->codec;
115 int reg;
116
117 reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
118 reg = (mute > 0) ? reg | AD193X_DAC_MASTER_MUTE : reg &
119 (~AD193X_DAC_MASTER_MUTE);
120 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
121
122 return 0;
123}
124
125static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
126 unsigned int rx_mask, int slots, int width)
127{
128 struct snd_soc_codec *codec = dai->codec;
129 int dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
130 int adc_reg = snd_soc_read(codec, AD193X_ADC_CTRL2);
131
132 dac_reg &= ~AD193X_DAC_CHAN_MASK;
133 adc_reg &= ~AD193X_ADC_CHAN_MASK;
134
135 switch (slots) {
136 case 2:
137 dac_reg |= AD193X_DAC_2_CHANNELS << AD193X_DAC_CHAN_SHFT;
138 adc_reg |= AD193X_ADC_2_CHANNELS << AD193X_ADC_CHAN_SHFT;
139 break;
140 case 4:
141 dac_reg |= AD193X_DAC_4_CHANNELS << AD193X_DAC_CHAN_SHFT;
142 adc_reg |= AD193X_ADC_4_CHANNELS << AD193X_ADC_CHAN_SHFT;
143 break;
144 case 8:
145 dac_reg |= AD193X_DAC_8_CHANNELS << AD193X_DAC_CHAN_SHFT;
146 adc_reg |= AD193X_ADC_8_CHANNELS << AD193X_ADC_CHAN_SHFT;
147 break;
148 case 16:
149 dac_reg |= AD193X_DAC_16_CHANNELS << AD193X_DAC_CHAN_SHFT;
150 adc_reg |= AD193X_ADC_16_CHANNELS << AD193X_ADC_CHAN_SHFT;
151 break;
152 default:
153 return -EINVAL;
154 }
155
156 snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg);
157 snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg);
158
159 return 0;
160}
161
162static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
163 unsigned int fmt)
164{
165 struct snd_soc_codec *codec = codec_dai->codec;
166 int adc_reg1, adc_reg2, dac_reg;
167
168 adc_reg1 = snd_soc_read(codec, AD193X_ADC_CTRL1);
169 adc_reg2 = snd_soc_read(codec, AD193X_ADC_CTRL2);
170 dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1);
171
172 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
173 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
174 */
175 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
176 case SND_SOC_DAIFMT_I2S:
177 adc_reg1 &= ~AD193X_ADC_SERFMT_MASK;
178 adc_reg1 |= AD193X_ADC_SERFMT_TDM;
179 break;
180 case SND_SOC_DAIFMT_DSP_A:
181 adc_reg1 &= ~AD193X_ADC_SERFMT_MASK;
182 adc_reg1 |= AD193X_ADC_SERFMT_AUX;
183 break;
184 default:
185 return -EINVAL;
186 }
187
188 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
189 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
190 adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
191 adc_reg2 &= ~AD193X_ADC_BCLK_INV;
192 dac_reg &= ~AD193X_DAC_LEFT_HIGH;
193 dac_reg &= ~AD193X_DAC_BCLK_INV;
194 break;
195 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
196 adc_reg2 |= AD193X_ADC_LEFT_HIGH;
197 adc_reg2 &= ~AD193X_ADC_BCLK_INV;
198 dac_reg |= AD193X_DAC_LEFT_HIGH;
199 dac_reg &= ~AD193X_DAC_BCLK_INV;
200 break;
201 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
202 adc_reg2 &= ~AD193X_ADC_LEFT_HIGH;
203 adc_reg2 |= AD193X_ADC_BCLK_INV;
204 dac_reg &= ~AD193X_DAC_LEFT_HIGH;
205 dac_reg |= AD193X_DAC_BCLK_INV;
206 break;
207
208 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
209 adc_reg2 |= AD193X_ADC_LEFT_HIGH;
210 adc_reg2 |= AD193X_ADC_BCLK_INV;
211 dac_reg |= AD193X_DAC_LEFT_HIGH;
212 dac_reg |= AD193X_DAC_BCLK_INV;
213 break;
214 default:
215 return -EINVAL;
216 }
217
218 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
219 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
220 adc_reg2 |= AD193X_ADC_LCR_MASTER;
221 adc_reg2 |= AD193X_ADC_BCLK_MASTER;
222 dac_reg |= AD193X_DAC_LCR_MASTER;
223 dac_reg |= AD193X_DAC_BCLK_MASTER;
224 break;
225 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
226 adc_reg2 |= AD193X_ADC_LCR_MASTER;
227 adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
228 dac_reg |= AD193X_DAC_LCR_MASTER;
229 dac_reg &= ~AD193X_DAC_BCLK_MASTER;
230 break;
231 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
232 adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
233 adc_reg2 |= AD193X_ADC_BCLK_MASTER;
234 dac_reg &= ~AD193X_DAC_LCR_MASTER;
235 dac_reg |= AD193X_DAC_BCLK_MASTER;
236 break;
237 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
238 adc_reg2 &= ~AD193X_ADC_LCR_MASTER;
239 adc_reg2 &= ~AD193X_ADC_BCLK_MASTER;
240 dac_reg &= ~AD193X_DAC_LCR_MASTER;
241 dac_reg &= ~AD193X_DAC_BCLK_MASTER;
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 snd_soc_write(codec, AD193X_ADC_CTRL1, adc_reg1);
248 snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg2);
249 snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg);
250
251 return 0;
252}
253
254static int ad193x_hw_params(struct snd_pcm_substream *substream,
255 struct snd_pcm_hw_params *params,
256 struct snd_soc_dai *dai)
257{
258 int word_len = 0, reg = 0;
259
260 struct snd_soc_pcm_runtime *rtd = substream->private_data;
261 struct snd_soc_device *socdev = rtd->socdev;
262 struct snd_soc_codec *codec = socdev->card->codec;
263
264 /* bit size */
265 switch (params_format(params)) {
266 case SNDRV_PCM_FORMAT_S16_LE:
267 word_len = 3;
268 break;
269 case SNDRV_PCM_FORMAT_S20_3LE:
270 word_len = 1;
271 break;
272 case SNDRV_PCM_FORMAT_S24_LE:
273 case SNDRV_PCM_FORMAT_S32_LE:
274 word_len = 0;
275 break;
276 }
277
278 reg = snd_soc_read(codec, AD193X_DAC_CTRL2);
279 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len;
280 snd_soc_write(codec, AD193X_DAC_CTRL2, reg);
281
282 reg = snd_soc_read(codec, AD193X_ADC_CTRL1);
283 reg = (reg & (~AD193X_ADC_WORD_LEN_MASK)) | word_len;
284 snd_soc_write(codec, AD193X_ADC_CTRL1, reg);
285
286 return 0;
287}
288
289static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
290{
291 struct snd_soc_codec *codec;
292 struct ad193x_priv *ad193x;
293 int ret;
294
295 if (ad193x_codec) {
296 dev_err(dev, "Another ad193x is registered\n");
297 return -EINVAL;
298 }
299
300 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
301 if (ad193x == NULL)
302 return -ENOMEM;
303
304 dev_set_drvdata(dev, ad193x);
305
306 codec = &ad193x->codec;
307 mutex_init(&codec->mutex);
308 codec->control_data = ctrl_data;
309 codec->dev = dev;
310 snd_soc_codec_set_drvdata(codec, ad193x);
311 codec->reg_cache = ad193x->reg_cache;
312 codec->reg_cache_size = AD193X_NUM_REGS;
313 codec->name = "AD193X";
314 codec->owner = THIS_MODULE;
315 codec->dai = &ad193x_dai;
316 codec->num_dai = 1;
317 INIT_LIST_HEAD(&codec->dapm_widgets);
318 INIT_LIST_HEAD(&codec->dapm_paths);
319
320 ad193x_dai.dev = codec->dev;
321 ad193x_codec = codec;
322
323 memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS);
324
325 if (bus_type == SND_SOC_I2C)
326 ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type);
327 else
328 ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
329 if (ret < 0) {
330 dev_err(codec->dev, "failed to set cache I/O: %d\n",
331 ret);
332 kfree(ad193x);
333 return ret;
334 }
335
336 /* default setting for ad193x */
337
338 /* unmute dac channels */
339 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
340 /* de-emphasis: 48kHz, powedown dac */
341 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
342 /* powerdown dac, dac in tdm mode */
343 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
344 /* high-pass filter enable */
345 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
346 /* sata delay=1, adc aux mode */
347 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
348 /* pll input: mclki/xi */
349 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
350 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
351
352 ret = snd_soc_register_codec(codec);
353 if (ret != 0) {
354 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
355 kfree(ad193x);
356 return ret;
357 }
358
359 ret = snd_soc_register_dai(&ad193x_dai);
360 if (ret != 0) {
361 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
362 snd_soc_unregister_codec(codec);
363 kfree(ad193x);
364 return ret;
365 }
366
367 return 0;
368}
369
370static int ad193x_bus_remove(struct device *dev)
371{
372 struct ad193x_priv *ad193x = dev_get_drvdata(dev);
373
374 snd_soc_unregister_dai(&ad193x_dai);
375 snd_soc_unregister_codec(&ad193x->codec);
376 kfree(ad193x);
377 ad193x_codec = NULL;
378
379 return 0;
380}
381
382static struct snd_soc_dai_ops ad193x_dai_ops = {
383 .hw_params = ad193x_hw_params,
384 .digital_mute = ad193x_mute,
385 .set_tdm_slot = ad193x_set_tdm_slot,
386 .set_fmt = ad193x_set_dai_fmt,
387};
388
389/* codec DAI instance */
390struct snd_soc_dai ad193x_dai = {
391 .name = "AD193X",
392 .playback = {
393 .stream_name = "Playback",
394 .channels_min = 2,
395 .channels_max = 8,
396 .rates = SNDRV_PCM_RATE_48000,
397 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
398 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
399 },
400 .capture = {
401 .stream_name = "Capture",
402 .channels_min = 2,
403 .channels_max = 4,
404 .rates = SNDRV_PCM_RATE_48000,
405 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
406 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
407 },
408 .ops = &ad193x_dai_ops,
409};
410EXPORT_SYMBOL_GPL(ad193x_dai);
411
412static int ad193x_probe(struct platform_device *pdev)
413{
414 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
415 struct snd_soc_codec *codec;
416 int ret = 0;
417
418 if (ad193x_codec == NULL) {
419 dev_err(&pdev->dev, "Codec device not registered\n");
420 return -ENODEV;
421 }
422
423 socdev->card->codec = ad193x_codec;
424 codec = ad193x_codec;
425
426 /* register pcms */
427 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
428 if (ret < 0) {
429 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
430 goto pcm_err;
431 }
432
433 snd_soc_add_controls(codec, ad193x_snd_controls,
434 ARRAY_SIZE(ad193x_snd_controls));
435 snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets,
436 ARRAY_SIZE(ad193x_dapm_widgets));
437 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
438
439pcm_err:
440 return ret;
441}
442
443/* power down chip */
444static int ad193x_remove(struct platform_device *pdev)
445{
446 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
447
448 snd_soc_free_pcms(socdev);
449 snd_soc_dapm_free(socdev);
450
451 return 0;
452}
453
454struct snd_soc_codec_device soc_codec_dev_ad193x = {
455 .probe = ad193x_probe,
456 .remove = ad193x_remove,
457};
458EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x);
459
460#if defined(CONFIG_SPI_MASTER)
461static int __devinit ad193x_spi_probe(struct spi_device *spi)
462{
463 return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI);
464}
465
466static int __devexit ad193x_spi_remove(struct spi_device *spi)
467{
468 return ad193x_bus_remove(&spi->dev);
469}
470
471static struct spi_driver ad193x_spi_driver = {
472 .driver = {
473 .name = "ad193x",
474 .owner = THIS_MODULE,
475 },
476 .probe = ad193x_spi_probe,
477 .remove = __devexit_p(ad193x_spi_remove),
478};
479#endif
480
481#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
482static const struct i2c_device_id ad193x_id[] = {
483 { "ad1936", 0 },
484 { "ad1937", 0 },
485 { }
486};
487MODULE_DEVICE_TABLE(i2c, ad193x_id);
488
489static int __devinit ad193x_i2c_probe(struct i2c_client *client,
490 const struct i2c_device_id *id)
491{
492 return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C);
493}
494
495static int __devexit ad193x_i2c_remove(struct i2c_client *client)
496{
497 return ad193x_bus_remove(&client->dev);
498}
499
500static struct i2c_driver ad193x_i2c_driver = {
501 .driver = {
502 .name = "ad193x",
503 },
504 .probe = ad193x_i2c_probe,
505 .remove = __devexit_p(ad193x_i2c_remove),
506 .id_table = ad193x_id,
507};
508#endif
509
510static int __init ad193x_modinit(void)
511{
512 int ret;
513
514#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
515 ret = i2c_add_driver(&ad193x_i2c_driver);
516 if (ret != 0) {
517 printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n",
518 ret);
519 }
520#endif
521
522#if defined(CONFIG_SPI_MASTER)
523 ret = spi_register_driver(&ad193x_spi_driver);
524 if (ret != 0) {
525 printk(KERN_ERR "Failed to register AD193X SPI driver: %d\n",
526 ret);
527 }
528#endif
529 return ret;
530}
531module_init(ad193x_modinit);
532
533static void __exit ad193x_modexit(void)
534{
535#if defined(CONFIG_SPI_MASTER)
536 spi_unregister_driver(&ad193x_spi_driver);
537#endif
538
539#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
540 i2c_del_driver(&ad193x_i2c_driver);
541#endif
542}
543module_exit(ad193x_modexit);
544
545MODULE_DESCRIPTION("ASoC ad193x driver");
546MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
547MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
new file mode 100644
index 000000000000..a03c880d52f9
--- /dev/null
+++ b/sound/soc/codecs/ad193x.h
@@ -0,0 +1,81 @@
1/*
2 * AD193X Audio Codec driver
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#ifndef __AD193X_H__
10#define __AD193X_H__
11
12#define AD193X_PLL_CLK_CTRL0 0x800
13#define AD193X_PLL_POWERDOWN 0x01
14#define AD193X_PLL_CLK_CTRL1 0x801
15#define AD193X_DAC_CTRL0 0x802
16#define AD193X_DAC_POWERDOWN 0x01
17#define AD193X_DAC_SERFMT_MASK 0xC0
18#define AD193X_DAC_SERFMT_STEREO (0 << 6)
19#define AD193X_DAC_SERFMT_TDM (1 << 6)
20#define AD193X_DAC_CTRL1 0x803
21#define AD193X_DAC_2_CHANNELS 0
22#define AD193X_DAC_4_CHANNELS 1
23#define AD193X_DAC_8_CHANNELS 2
24#define AD193X_DAC_16_CHANNELS 3
25#define AD193X_DAC_CHAN_SHFT 1
26#define AD193X_DAC_CHAN_MASK (3 << AD193X_DAC_CHAN_SHFT)
27#define AD193X_DAC_LCR_MASTER (1 << 4)
28#define AD193X_DAC_BCLK_MASTER (1 << 5)
29#define AD193X_DAC_LEFT_HIGH (1 << 3)
30#define AD193X_DAC_BCLK_INV (1 << 7)
31#define AD193X_DAC_CTRL2 0x804
32#define AD193X_DAC_WORD_LEN_MASK 0xC
33#define AD193X_DAC_MASTER_MUTE 1
34#define AD193X_DAC_CHNL_MUTE 0x805
35#define AD193X_DACL1_MUTE 0
36#define AD193X_DACR1_MUTE 1
37#define AD193X_DACL2_MUTE 2
38#define AD193X_DACR2_MUTE 3
39#define AD193X_DACL3_MUTE 4
40#define AD193X_DACR3_MUTE 5
41#define AD193X_DACL4_MUTE 6
42#define AD193X_DACR4_MUTE 7
43#define AD193X_DAC_L1_VOL 0x806
44#define AD193X_DAC_R1_VOL 0x807
45#define AD193X_DAC_L2_VOL 0x808
46#define AD193X_DAC_R2_VOL 0x809
47#define AD193X_DAC_L3_VOL 0x80a
48#define AD193X_DAC_R3_VOL 0x80b
49#define AD193X_DAC_L4_VOL 0x80c
50#define AD193X_DAC_R4_VOL 0x80d
51#define AD193X_ADC_CTRL0 0x80e
52#define AD193X_ADC_POWERDOWN 0x01
53#define AD193X_ADC_HIGHPASS_FILTER 1
54#define AD193X_ADCL1_MUTE 2
55#define AD193X_ADCR1_MUTE 3
56#define AD193X_ADCL2_MUTE 4
57#define AD193X_ADCR2_MUTE 5
58#define AD193X_ADC_CTRL1 0x80f
59#define AD193X_ADC_SERFMT_MASK 0x60
60#define AD193X_ADC_SERFMT_STEREO (0 << 5)
61#define AD193X_ADC_SERFMT_TDM (1 << 2)
62#define AD193X_ADC_SERFMT_AUX (2 << 5)
63#define AD193X_ADC_WORD_LEN_MASK 0x3
64#define AD193X_ADC_CTRL2 0x810
65#define AD193X_ADC_2_CHANNELS 0
66#define AD193X_ADC_4_CHANNELS 1
67#define AD193X_ADC_8_CHANNELS 2
68#define AD193X_ADC_16_CHANNELS 3
69#define AD193X_ADC_CHAN_SHFT 4
70#define AD193X_ADC_CHAN_MASK (3 << AD193X_ADC_CHAN_SHFT)
71#define AD193X_ADC_LCR_MASTER (1 << 3)
72#define AD193X_ADC_BCLK_MASTER (1 << 6)
73#define AD193X_ADC_LEFT_HIGH (1 << 2)
74#define AD193X_ADC_BCLK_INV (1 << 1)
75
76#define AD193X_NUM_REGS 17
77
78extern struct snd_soc_dai ad193x_dai;
79extern struct snd_soc_codec_device soc_codec_dev_ad193x;
80
81#endif
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index bdeb10dfd887..192aebda3029 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -222,7 +222,7 @@ static int ak4104_spi_probe(struct spi_device *spi)
222 codec->owner = THIS_MODULE; 222 codec->owner = THIS_MODULE;
223 codec->dai = &ak4104_dai; 223 codec->dai = &ak4104_dai;
224 codec->num_dai = 1; 224 codec->num_dai = 1;
225 codec->private_data = ak4104; 225 snd_soc_codec_set_drvdata(codec, ak4104);
226 codec->control_data = spi; 226 codec->control_data = spi;
227 codec->reg_cache = ak4104->reg_cache; 227 codec->reg_cache = ak4104->reg_cache;
228 codec->reg_cache_size = AK4104_NUM_REGS; 228 codec->reg_cache_size = AK4104_NUM_REGS;
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 352d1d08dbd9..d4253675b2d3 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -302,7 +302,7 @@ static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
302 int clk_id, unsigned int freq, int dir) 302 int clk_id, unsigned int freq, int dir)
303{ 303{
304 struct snd_soc_codec *codec = codec_dai->codec; 304 struct snd_soc_codec *codec = codec_dai->codec;
305 struct ak4535_priv *ak4535 = codec->private_data; 305 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
306 306
307 ak4535->sysclk = freq; 307 ak4535->sysclk = freq;
308 return 0; 308 return 0;
@@ -315,7 +315,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
315 struct snd_soc_pcm_runtime *rtd = substream->private_data; 315 struct snd_soc_pcm_runtime *rtd = substream->private_data;
316 struct snd_soc_device *socdev = rtd->socdev; 316 struct snd_soc_device *socdev = rtd->socdev;
317 struct snd_soc_codec *codec = socdev->card->codec; 317 struct snd_soc_codec *codec = socdev->card->codec;
318 struct ak4535_priv *ak4535 = codec->private_data; 318 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
319 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); 319 u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
320 int rate = params_rate(params), fs = 256; 320 int rate = params_rate(params), fs = 256;
321 321
@@ -446,7 +446,6 @@ static int ak4535_resume(struct platform_device *pdev)
446 struct snd_soc_codec *codec = socdev->card->codec; 446 struct snd_soc_codec *codec = socdev->card->codec;
447 ak4535_sync(codec); 447 ak4535_sync(codec);
448 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 448 ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
449 ak4535_set_bias_level(codec, codec->suspend_bias_level);
450 return 0; 449 return 0;
451} 450}
452 451
@@ -600,7 +599,7 @@ static int ak4535_probe(struct platform_device *pdev)
600 return -ENOMEM; 599 return -ENOMEM;
601 } 600 }
602 601
603 codec->private_data = ak4535; 602 snd_soc_codec_set_drvdata(codec, ak4535);
604 socdev->card->codec = codec; 603 socdev->card->codec = codec;
605 mutex_init(&codec->mutex); 604 mutex_init(&codec->mutex);
606 INIT_LIST_HEAD(&codec->dapm_widgets); 605 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -617,7 +616,7 @@ static int ak4535_probe(struct platform_device *pdev)
617#endif 616#endif
618 617
619 if (ret != 0) { 618 if (ret != 0) {
620 kfree(codec->private_data); 619 kfree(snd_soc_codec_get_drvdata(codec));
621 kfree(codec); 620 kfree(codec);
622 } 621 }
623 return ret; 622 return ret;
@@ -639,7 +638,7 @@ static int ak4535_remove(struct platform_device *pdev)
639 i2c_unregister_device(codec->control_data); 638 i2c_unregister_device(codec->control_data);
640 i2c_del_driver(&ak4535_i2c_driver); 639 i2c_del_driver(&ak4535_i2c_driver);
641#endif 640#endif
642 kfree(codec->private_data); 641 kfree(snd_soc_codec_get_drvdata(codec));
643 kfree(codec); 642 kfree(codec);
644 643
645 return 0; 644 return 0;
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 729859cf6ca8..7528a54102b5 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -81,12 +81,39 @@
81 81
82#define AK4642_CACHEREGNUM 0x25 82#define AK4642_CACHEREGNUM 0x25
83 83
84/* PW_MGMT2 */
85#define HPMTN (1 << 6)
86#define PMHPL (1 << 5)
87#define PMHPR (1 << 4)
88#define MS (1 << 3) /* master/slave select */
89#define MCKO (1 << 1)
90#define PMPLL (1 << 0)
91
92#define PMHP_MASK (PMHPL | PMHPR)
93#define PMHP PMHP_MASK
94
95/* MD_CTL1 */
96#define PLL3 (1 << 7)
97#define PLL2 (1 << 6)
98#define PLL1 (1 << 5)
99#define PLL0 (1 << 4)
100#define PLL_MASK (PLL3 | PLL2 | PLL1 | PLL0)
101
102#define BCKO_MASK (1 << 3)
103#define BCKO_64 BCKO_MASK
104
105/* MD_CTL2 */
106#define FS0 (1 << 0)
107#define FS1 (1 << 1)
108#define FS2 (1 << 2)
109#define FS3 (1 << 5)
110#define FS_MASK (FS0 | FS1 | FS2 | FS3)
111
84struct snd_soc_codec_device soc_codec_dev_ak4642; 112struct snd_soc_codec_device soc_codec_dev_ak4642;
85 113
86/* codec private data */ 114/* codec private data */
87struct ak4642_priv { 115struct ak4642_priv {
88 struct snd_soc_codec codec; 116 struct snd_soc_codec codec;
89 unsigned int sysclk;
90}; 117};
91 118
92static struct snd_soc_codec *ak4642_codec; 119static struct snd_soc_codec *ak4642_codec;
@@ -177,17 +204,12 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
177 * 204 *
178 * PLL, Master Mode 205 * PLL, Master Mode
179 * Audio I/F Format :MSB justified (ADC & DAC) 206 * Audio I/F Format :MSB justified (ADC & DAC)
180 * Sampling Frequency: 44.1kHz 207 * Digital Volume: -8dB
181 * Digital Volume: −8dB
182 * Bass Boost Level : Middle 208 * Bass Boost Level : Middle
183 * 209 *
184 * This operation came from example code of 210 * This operation came from example code of
185 * "ASAHI KASEI AK4642" (japanese) manual p97. 211 * "ASAHI KASEI AK4642" (japanese) manual p97.
186 *
187 * Example code use 0x39, 0x79 value for 0x01 address,
188 * But we need MCKO (0x02) bit now
189 */ 212 */
190 ak4642_write(codec, 0x05, 0x27);
191 ak4642_write(codec, 0x0f, 0x09); 213 ak4642_write(codec, 0x0f, 0x09);
192 ak4642_write(codec, 0x0e, 0x19); 214 ak4642_write(codec, 0x0e, 0x19);
193 ak4642_write(codec, 0x09, 0x91); 215 ak4642_write(codec, 0x09, 0x91);
@@ -195,15 +217,14 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
195 ak4642_write(codec, 0x0a, 0x28); 217 ak4642_write(codec, 0x0a, 0x28);
196 ak4642_write(codec, 0x0d, 0x28); 218 ak4642_write(codec, 0x0d, 0x28);
197 ak4642_write(codec, 0x00, 0x64); 219 ak4642_write(codec, 0x00, 0x64);
198 ak4642_write(codec, 0x01, 0x3b); /* + MCKO bit */ 220 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
199 ak4642_write(codec, 0x01, 0x7b); /* + MCKO bit */ 221 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
200 } else { 222 } else {
201 /* 223 /*
202 * start stereo input 224 * start stereo input
203 * 225 *
204 * PLL Master Mode 226 * PLL Master Mode
205 * Audio I/F Format:MSB justified (ADC & DAC) 227 * Audio I/F Format:MSB justified (ADC & DAC)
206 * Sampling Frequency:44.1kHz
207 * Pre MIC AMP:+20dB 228 * Pre MIC AMP:+20dB
208 * MIC Power On 229 * MIC Power On
209 * ALC setting:Refer to Table 35 230 * ALC setting:Refer to Table 35
@@ -212,7 +233,6 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
212 * This operation came from example code of 233 * This operation came from example code of
213 * "ASAHI KASEI AK4642" (japanese) manual p94. 234 * "ASAHI KASEI AK4642" (japanese) manual p94.
214 */ 235 */
215 ak4642_write(codec, 0x05, 0x27);
216 ak4642_write(codec, 0x02, 0x05); 236 ak4642_write(codec, 0x02, 0x05);
217 ak4642_write(codec, 0x06, 0x3c); 237 ak4642_write(codec, 0x06, 0x3c);
218 ak4642_write(codec, 0x08, 0xe1); 238 ak4642_write(codec, 0x08, 0xe1);
@@ -233,8 +253,8 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
233 253
234 if (is_play) { 254 if (is_play) {
235 /* stop headphone output */ 255 /* stop headphone output */
236 ak4642_write(codec, 0x01, 0x3b); 256 snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0);
237 ak4642_write(codec, 0x01, 0x0b); 257 snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0);
238 ak4642_write(codec, 0x00, 0x40); 258 ak4642_write(codec, 0x00, 0x40);
239 ak4642_write(codec, 0x0e, 0x11); 259 ak4642_write(codec, 0x0e, 0x11);
240 ak4642_write(codec, 0x0f, 0x08); 260 ak4642_write(codec, 0x0f, 0x08);
@@ -250,9 +270,111 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
250 int clk_id, unsigned int freq, int dir) 270 int clk_id, unsigned int freq, int dir)
251{ 271{
252 struct snd_soc_codec *codec = codec_dai->codec; 272 struct snd_soc_codec *codec = codec_dai->codec;
253 struct ak4642_priv *ak4642 = codec->private_data; 273 u8 pll;
274
275 switch (freq) {
276 case 11289600:
277 pll = PLL2;
278 break;
279 case 12288000:
280 pll = PLL2 | PLL0;
281 break;
282 case 12000000:
283 pll = PLL2 | PLL1;
284 break;
285 case 24000000:
286 pll = PLL2 | PLL1 | PLL0;
287 break;
288 case 13500000:
289 pll = PLL3 | PLL2;
290 break;
291 case 27000000:
292 pll = PLL3 | PLL2 | PLL0;
293 break;
294 default:
295 return -EINVAL;
296 }
297 snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll);
298
299 return 0;
300}
301
302static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
303{
304 struct snd_soc_codec *codec = dai->codec;
305 u8 data;
306 u8 bcko;
307
308 data = MCKO | PMPLL; /* use MCKO */
309 bcko = 0;
310
311 /* set master/slave audio interface */
312 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
313 case SND_SOC_DAIFMT_CBM_CFM:
314 data |= MS;
315 bcko = BCKO_64;
316 break;
317 case SND_SOC_DAIFMT_CBS_CFS:
318 break;
319 default:
320 return -EINVAL;
321 }
322 snd_soc_update_bits(codec, PW_MGMT2, MS, data);
323 snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
324
325 return 0;
326}
327
328static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai)
331{
332 struct snd_soc_codec *codec = dai->codec;
333 u8 rate;
334
335 switch (params_rate(params)) {
336 case 7350:
337 rate = FS2;
338 break;
339 case 8000:
340 rate = 0;
341 break;
342 case 11025:
343 rate = FS2 | FS0;
344 break;
345 case 12000:
346 rate = FS0;
347 break;
348 case 14700:
349 rate = FS2 | FS1;
350 break;
351 case 16000:
352 rate = FS1;
353 break;
354 case 22050:
355 rate = FS2 | FS1 | FS0;
356 break;
357 case 24000:
358 rate = FS1 | FS0;
359 break;
360 case 29400:
361 rate = FS3 | FS2 | FS1;
362 break;
363 case 32000:
364 rate = FS3 | FS1;
365 break;
366 case 44100:
367 rate = FS3 | FS2 | FS1 | FS0;
368 break;
369 case 48000:
370 rate = FS3 | FS1 | FS0;
371 break;
372 default:
373 return -EINVAL;
374 break;
375 }
376 snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
254 377
255 ak4642->sysclk = freq;
256 return 0; 378 return 0;
257} 379}
258 380
@@ -260,6 +382,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = {
260 .startup = ak4642_dai_startup, 382 .startup = ak4642_dai_startup,
261 .shutdown = ak4642_dai_shutdown, 383 .shutdown = ak4642_dai_shutdown,
262 .set_sysclk = ak4642_dai_set_sysclk, 384 .set_sysclk = ak4642_dai_set_sysclk,
385 .set_fmt = ak4642_dai_set_fmt,
386 .hw_params = ak4642_dai_hw_params,
263}; 387};
264 388
265struct snd_soc_dai ak4642_dai = { 389struct snd_soc_dai ak4642_dai = {
@@ -277,6 +401,7 @@ struct snd_soc_dai ak4642_dai = {
277 .rates = SNDRV_PCM_RATE_8000_48000, 401 .rates = SNDRV_PCM_RATE_8000_48000,
278 .formats = SNDRV_PCM_FMTBIT_S16_LE }, 402 .formats = SNDRV_PCM_FMTBIT_S16_LE },
279 .ops = &ak4642_dai_ops, 403 .ops = &ak4642_dai_ops,
404 .symmetric_rates = 1,
280}; 405};
281EXPORT_SYMBOL_GPL(ak4642_dai); 406EXPORT_SYMBOL_GPL(ak4642_dai);
282 407
@@ -307,7 +432,7 @@ static int ak4642_init(struct ak4642_priv *ak4642)
307 INIT_LIST_HEAD(&codec->dapm_widgets); 432 INIT_LIST_HEAD(&codec->dapm_widgets);
308 INIT_LIST_HEAD(&codec->dapm_paths); 433 INIT_LIST_HEAD(&codec->dapm_paths);
309 434
310 codec->private_data = ak4642; 435 snd_soc_codec_set_drvdata(codec, ak4642);
311 codec->name = "AK4642"; 436 codec->name = "AK4642";
312 codec->owner = THIS_MODULE; 437 codec->owner = THIS_MODULE;
313 codec->read = ak4642_read_reg_cache; 438 codec->read = ak4642_read_reg_cache;
@@ -338,26 +463,6 @@ static int ak4642_init(struct ak4642_priv *ak4642)
338 goto reg_cache_err; 463 goto reg_cache_err;
339 } 464 }
340 465
341 /*
342 * clock setting
343 *
344 * Audio I/F Format: MSB justified (ADC & DAC)
345 * BICK frequency at Master Mode: 64fs
346 * Input Master Clock Select at PLL Mode: 11.2896MHz
347 * MCKO: Enable
348 * Sampling Frequency: 44.1kHz
349 *
350 * This operation came from example code of
351 * "ASAHI KASEI AK4642" (japanese) manual p89.
352 *
353 * please fix-me
354 */
355 ak4642_write(codec, 0x01, 0x08);
356 ak4642_write(codec, 0x04, 0x4a);
357 ak4642_write(codec, 0x05, 0x27);
358 ak4642_write(codec, 0x00, 0x40);
359 ak4642_write(codec, 0x01, 0x0b);
360
361 return ret; 466 return ret;
362 467
363reg_cache_err: 468reg_cache_err:
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 926797a014c7..87566932a3b1 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -702,7 +702,7 @@ static int ak4671_register(struct ak4671_priv *ak4671,
702 INIT_LIST_HEAD(&codec->dapm_widgets); 702 INIT_LIST_HEAD(&codec->dapm_widgets);
703 INIT_LIST_HEAD(&codec->dapm_paths); 703 INIT_LIST_HEAD(&codec->dapm_paths);
704 704
705 codec->private_data = ak4671; 705 snd_soc_codec_set_drvdata(codec, ak4671);
706 codec->name = "AK4671"; 706 codec->name = "AK4671";
707 codec->owner = THIS_MODULE; 707 codec->owner = THIS_MODULE;
708 codec->bias_level = SND_SOC_BIAS_OFF; 708 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
new file mode 100644
index 000000000000..a320fb5a0e26
--- /dev/null
+++ b/sound/soc/codecs/cq93vc.c
@@ -0,0 +1,299 @@
1/*
2 * ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/io.h>
26#include <linux/delay.h>
27#include <linux/pm.h>
28#include <linux/platform_device.h>
29#include <linux/device.h>
30#include <linux/slab.h>
31#include <linux/clk.h>
32#include <linux/mfd/davinci_voicecodec.h>
33
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/soc.h>
38#include <sound/soc-dai.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h>
41
42#include <mach/dm365.h>
43
44#include "cq93vc.h"
45
46static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
47 unsigned int reg)
48{
49 struct davinci_vc *davinci_vc = codec->control_data;
50
51 return readl(davinci_vc->base + reg);
52}
53
54static inline int cq93vc_write(struct snd_soc_codec *codec, unsigned int reg,
55 unsigned int value)
56{
57 struct davinci_vc *davinci_vc = codec->control_data;
58
59 writel(value, davinci_vc->base + reg);
60
61 return 0;
62}
63
64static const struct snd_kcontrol_new cq93vc_snd_controls[] = {
65 SOC_SINGLE("PGA Capture Volume", DAVINCI_VC_REG05, 0, 0x03, 0),
66 SOC_SINGLE("Mono DAC Playback Volume", DAVINCI_VC_REG09, 0, 0x3f, 0),
67};
68
69static int cq93vc_mute(struct snd_soc_dai *dai, int mute)
70{
71 struct snd_soc_codec *codec = dai->codec;
72 u8 reg = cq93vc_read(codec, DAVINCI_VC_REG09) & ~DAVINCI_VC_REG09_MUTE;
73
74 if (mute)
75 cq93vc_write(codec, DAVINCI_VC_REG09,
76 reg | DAVINCI_VC_REG09_MUTE);
77 else
78 cq93vc_write(codec, DAVINCI_VC_REG09, reg);
79
80 return 0;
81}
82
83static int cq93vc_set_dai_sysclk(struct snd_soc_dai *codec_dai,
84 int clk_id, unsigned int freq, int dir)
85{
86 struct snd_soc_codec *codec = codec_dai->codec;
87 struct davinci_vc *davinci_vc = codec->control_data;
88
89 switch (freq) {
90 case 22579200:
91 case 27000000:
92 case 33868800:
93 davinci_vc->cq93vc.sysclk = freq;
94 return 0;
95 }
96
97 return -EINVAL;
98}
99
100static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
101 enum snd_soc_bias_level level)
102{
103 switch (level) {
104 case SND_SOC_BIAS_ON:
105 cq93vc_write(codec, DAVINCI_VC_REG12,
106 DAVINCI_VC_REG12_POWER_ALL_ON);
107 break;
108 case SND_SOC_BIAS_PREPARE:
109 break;
110 case SND_SOC_BIAS_STANDBY:
111 cq93vc_write(codec, DAVINCI_VC_REG12,
112 DAVINCI_VC_REG12_POWER_ALL_OFF);
113 break;
114 case SND_SOC_BIAS_OFF:
115 /* force all power off */
116 cq93vc_write(codec, DAVINCI_VC_REG12,
117 DAVINCI_VC_REG12_POWER_ALL_OFF);
118 break;
119 }
120 codec->bias_level = level;
121
122 return 0;
123}
124
125#define CQ93VC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
126#define CQ93VC_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
127
128static struct snd_soc_dai_ops cq93vc_dai_ops = {
129 .digital_mute = cq93vc_mute,
130 .set_sysclk = cq93vc_set_dai_sysclk,
131};
132
133struct snd_soc_dai cq93vc_dai = {
134 .name = "CQ93VC",
135 .playback = {
136 .stream_name = "Playback",
137 .channels_min = 1,
138 .channels_max = 2,
139 .rates = CQ93VC_RATES,
140 .formats = CQ93VC_FORMATS,},
141 .capture = {
142 .stream_name = "Capture",
143 .channels_min = 1,
144 .channels_max = 2,
145 .rates = CQ93VC_RATES,
146 .formats = CQ93VC_FORMATS,},
147 .ops = &cq93vc_dai_ops,
148};
149EXPORT_SYMBOL_GPL(cq93vc_dai);
150
151static int cq93vc_resume(struct platform_device *pdev)
152{
153 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
154 struct snd_soc_codec *codec = socdev->card->codec;
155
156 cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
157
158 return 0;
159}
160
161static struct snd_soc_codec *cq93vc_codec;
162
163static int cq93vc_probe(struct platform_device *pdev)
164{
165 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
166 struct device *dev = &pdev->dev;
167 struct snd_soc_codec *codec;
168 int ret;
169
170 socdev->card->codec = cq93vc_codec;
171 codec = socdev->card->codec;
172
173 /* Register pcms */
174 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
175 if (ret < 0) {
176 dev_err(dev, "%s: failed to create pcms\n", pdev->name);
177 return ret;
178 }
179
180 /* Set controls */
181 snd_soc_add_controls(codec, cq93vc_snd_controls,
182 ARRAY_SIZE(cq93vc_snd_controls));
183
184 /* Off, with power on */
185 cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
186
187 return 0;
188}
189
190static int cq93vc_remove(struct platform_device *pdev)
191{
192 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
193
194 snd_soc_free_pcms(socdev);
195 snd_soc_dapm_free(socdev);
196
197 return 0;
198}
199
200struct snd_soc_codec_device soc_codec_dev_cq93vc = {
201 .probe = cq93vc_probe,
202 .remove = cq93vc_remove,
203 .resume = cq93vc_resume,
204};
205EXPORT_SYMBOL_GPL(soc_codec_dev_cq93vc);
206
207static __init int cq93vc_codec_probe(struct platform_device *pdev)
208{
209 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
210 struct snd_soc_codec *codec;
211 int ret;
212
213 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
214 if (codec == NULL) {
215 dev_dbg(davinci_vc->dev,
216 "could not allocate memory for codec data\n");
217 return -ENOMEM;
218 }
219
220 davinci_vc->cq93vc.codec = codec;
221
222 cq93vc_dai.dev = &pdev->dev;
223
224 mutex_init(&codec->mutex);
225 INIT_LIST_HEAD(&codec->dapm_widgets);
226 INIT_LIST_HEAD(&codec->dapm_paths);
227 codec->dev = &pdev->dev;
228 codec->name = "CQ93VC";
229 codec->owner = THIS_MODULE;
230 codec->read = cq93vc_read;
231 codec->write = cq93vc_write;
232 codec->set_bias_level = cq93vc_set_bias_level;
233 codec->dai = &cq93vc_dai;
234 codec->num_dai = 1;
235 codec->control_data = davinci_vc;
236
237 cq93vc_codec = codec;
238
239 ret = snd_soc_register_codec(codec);
240 if (ret) {
241 dev_err(davinci_vc->dev, "failed to register codec\n");
242 goto fail1;
243 }
244
245 ret = snd_soc_register_dai(&cq93vc_dai);
246 if (ret) {
247 dev_err(davinci_vc->dev, "could register dai\n");
248 goto fail2;
249 }
250 return 0;
251
252fail2:
253 snd_soc_unregister_codec(codec);
254
255fail1:
256 kfree(codec);
257 cq93vc_codec = NULL;
258
259 return ret;
260}
261
262static int __devexit cq93vc_codec_remove(struct platform_device *pdev)
263{
264 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
265 struct snd_soc_codec *codec = socdev->card->codec;
266
267 snd_soc_unregister_dai(&cq93vc_dai);
268 snd_soc_unregister_codec(&codec);
269
270 kfree(codec);
271 cq93vc_codec = NULL;
272
273 return 0;
274}
275
276static struct platform_driver cq93vc_codec_driver = {
277 .driver = {
278 .name = "cq93vc",
279 .owner = THIS_MODULE,
280 },
281 .probe = cq93vc_codec_probe,
282 .remove = __devexit_p(cq93vc_codec_remove),
283};
284
285static __init int cq93vc_init(void)
286{
287 return platform_driver_probe(&cq93vc_codec_driver, cq93vc_codec_probe);
288}
289module_init(cq93vc_init);
290
291static __exit void cq93vc_exit(void)
292{
293 platform_driver_unregister(&cq93vc_codec_driver);
294}
295module_exit(cq93vc_exit);
296
297MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC CQ0093 Voice Codec Driver");
298MODULE_AUTHOR("Miguel Aguilar");
299MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cq93vc.h b/sound/soc/codecs/cq93vc.h
new file mode 100644
index 000000000000..845b1968ef9c
--- /dev/null
+++ b/sound/soc/codecs/cq93vc.h
@@ -0,0 +1,29 @@
1/*
2 * ALSA SoC CQ0093 Voice Codec Driver for DaVinci platforms
3 *
4 * Copyright (C) 2010 Texas Instruments, Inc
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _CQ93VC_H
24#define _CQ93VC_H
25
26extern struct snd_soc_dai cq93vc_dai;
27extern struct snd_soc_codec_device soc_codec_dev_cq93vc;
28
29#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 81a62d198b70..30d949239def 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -211,7 +211,7 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
211 int clk_id, unsigned int freq, int dir) 211 int clk_id, unsigned int freq, int dir)
212{ 212{
213 struct snd_soc_codec *codec = codec_dai->codec; 213 struct snd_soc_codec *codec = codec_dai->codec;
214 struct cs4270_private *cs4270 = codec->private_data; 214 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
215 unsigned int rates = 0; 215 unsigned int rates = 0;
216 unsigned int rate_min = -1; 216 unsigned int rate_min = -1;
217 unsigned int rate_max = 0; 217 unsigned int rate_max = 0;
@@ -270,7 +270,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
270 unsigned int format) 270 unsigned int format)
271{ 271{
272 struct snd_soc_codec *codec = codec_dai->codec; 272 struct snd_soc_codec *codec = codec_dai->codec;
273 struct cs4270_private *cs4270 = codec->private_data; 273 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
274 int ret = 0; 274 int ret = 0;
275 275
276 /* set DAI format */ 276 /* set DAI format */
@@ -412,7 +412,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
412 struct snd_soc_pcm_runtime *rtd = substream->private_data; 412 struct snd_soc_pcm_runtime *rtd = substream->private_data;
413 struct snd_soc_device *socdev = rtd->socdev; 413 struct snd_soc_device *socdev = rtd->socdev;
414 struct snd_soc_codec *codec = socdev->card->codec; 414 struct snd_soc_codec *codec = socdev->card->codec;
415 struct cs4270_private *cs4270 = codec->private_data; 415 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
416 int ret; 416 int ret;
417 unsigned int i; 417 unsigned int i;
418 unsigned int rate; 418 unsigned int rate;
@@ -491,7 +491,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
491static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute) 491static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute)
492{ 492{
493 struct snd_soc_codec *codec = dai->codec; 493 struct snd_soc_codec *codec = dai->codec;
494 struct cs4270_private *cs4270 = codec->private_data; 494 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
495 int reg6; 495 int reg6;
496 496
497 reg6 = snd_soc_read(codec, CS4270_MUTE); 497 reg6 = snd_soc_read(codec, CS4270_MUTE);
@@ -524,7 +524,7 @@ static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol) 524 struct snd_ctl_elem_value *ucontrol)
525{ 525{
526 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 526 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct cs4270_private *cs4270 = codec->private_data; 527 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
528 int left = !ucontrol->value.integer.value[0]; 528 int left = !ucontrol->value.integer.value[0];
529 int right = !ucontrol->value.integer.value[1]; 529 int right = !ucontrol->value.integer.value[1];
530 530
@@ -600,7 +600,7 @@ static int cs4270_probe(struct platform_device *pdev)
600{ 600{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = cs4270_codec; 602 struct snd_soc_codec *codec = cs4270_codec;
603 struct cs4270_private *cs4270 = codec->private_data; 603 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
604 int i, ret; 604 int i, ret;
605 605
606 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 606 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
@@ -657,7 +657,7 @@ static int cs4270_remove(struct platform_device *pdev)
657{ 657{
658 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 658 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
659 struct snd_soc_codec *codec = cs4270_codec; 659 struct snd_soc_codec *codec = cs4270_codec;
660 struct cs4270_private *cs4270 = codec->private_data; 660 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
661 661
662 snd_soc_free_pcms(socdev); 662 snd_soc_free_pcms(socdev);
663 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); 663 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
@@ -730,7 +730,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
730 codec->owner = THIS_MODULE; 730 codec->owner = THIS_MODULE;
731 codec->dai = &cs4270_dai; 731 codec->dai = &cs4270_dai;
732 codec->num_dai = 1; 732 codec->num_dai = 1;
733 codec->private_data = cs4270; 733 snd_soc_codec_set_drvdata(codec, cs4270);
734 codec->control_data = i2c_client; 734 codec->control_data = i2c_client;
735 codec->read = cs4270_read_reg_cache; 735 codec->read = cs4270_read_reg_cache;
736 codec->write = cs4270_i2c_write; 736 codec->write = cs4270_i2c_write;
@@ -843,7 +843,7 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
843static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 843static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
844{ 844{
845 struct snd_soc_codec *codec = cs4270_codec; 845 struct snd_soc_codec *codec = cs4270_codec;
846 struct cs4270_private *cs4270 = codec->private_data; 846 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
847 int reg, ret; 847 int reg, ret;
848 848
849 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; 849 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
@@ -863,7 +863,7 @@ static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
863static int cs4270_soc_resume(struct platform_device *pdev) 863static int cs4270_soc_resume(struct platform_device *pdev)
864{ 864{
865 struct snd_soc_codec *codec = cs4270_codec; 865 struct snd_soc_codec *codec = cs4270_codec;
866 struct cs4270_private *cs4270 = codec->private_data; 866 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
867 struct i2c_client *i2c_client = codec->control_data; 867 struct i2c_client *i2c_client = codec->control_data;
868 int reg; 868 int reg;
869 869
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 9f169c477108..f07a415c753f 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -387,7 +387,7 @@ static int cx20442_register(struct cx20442_priv *cx20442)
387 387
388 codec->name = "CX20442"; 388 codec->name = "CX20442";
389 codec->owner = THIS_MODULE; 389 codec->owner = THIS_MODULE;
390 codec->private_data = cx20442; 390 snd_soc_codec_set_drvdata(codec, cx20442);
391 391
392 codec->dai = &cx20442_dai; 392 codec->dai = &cx20442_dai;
393 codec->num_dai = 1; 393 codec->num_dai = 1;
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 366daf1d044e..75af2d6e0e78 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -56,8 +56,14 @@
56#define DA7210_DAI_SRC_SEL 0x25 56#define DA7210_DAI_SRC_SEL 0x25
57#define DA7210_DAI_CFG1 0x26 57#define DA7210_DAI_CFG1 0x26
58#define DA7210_DAI_CFG3 0x28 58#define DA7210_DAI_CFG3 0x28
59#define DA7210_PLL_DIV1 0x29
60#define DA7210_PLL_DIV2 0x2A
59#define DA7210_PLL_DIV3 0x2B 61#define DA7210_PLL_DIV3 0x2B
60#define DA7210_PLL 0x2C 62#define DA7210_PLL 0x2C
63#define DA7210_A_HID_UNLOCK 0x8A
64#define DA7210_A_TEST_UNLOCK 0x8B
65#define DA7210_A_PLL1 0x90
66#define DA7210_A_CP_MODE 0xA7
61 67
62/* STARTUP1 bit fields */ 68/* STARTUP1 bit fields */
63#define DA7210_SC_MST_EN (1 << 0) 69#define DA7210_SC_MST_EN (1 << 0)
@@ -75,15 +81,14 @@
75/* INMIX_R bit fields */ 81/* INMIX_R bit fields */
76#define DA7210_IN_R_EN (1 << 7) 82#define DA7210_IN_R_EN (1 << 7)
77 83
78/* ADC_HPF bit fields */
79#define DA7210_ADC_VOICE_EN (1 << 7)
80
81/* ADC bit fields */ 84/* ADC bit fields */
82#define DA7210_ADC_L_EN (1 << 3) 85#define DA7210_ADC_L_EN (1 << 3)
83#define DA7210_ADC_R_EN (1 << 7) 86#define DA7210_ADC_R_EN (1 << 7)
84 87
85/* DAC_HPF fields */ 88/* DAC/ADC HPF fields */
86#define DA7210_DAC_VOICE_EN (1 << 7) 89#define DA7210_VOICE_F0_MASK (0x7 << 4)
90#define DA7210_VOICE_F0_25 (1 << 4)
91#define DA7210_VOICE_EN (1 << 7)
87 92
88/* DAC_SEL bit fields */ 93/* DAC_SEL bit fields */
89#define DA7210_DAC_L_SRC_DAI_L (4 << 0) 94#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
@@ -124,7 +129,19 @@
124#define DA7210_PLL_BYP (1 << 6) 129#define DA7210_PLL_BYP (1 << 6)
125 130
126/* PLL bit fields */ 131/* PLL bit fields */
127#define DA7210_PLL_FS_48000 (11 << 0) 132#define DA7210_PLL_FS_MASK (0xF << 0)
133#define DA7210_PLL_FS_8000 (0x1 << 0)
134#define DA7210_PLL_FS_11025 (0x2 << 0)
135#define DA7210_PLL_FS_12000 (0x3 << 0)
136#define DA7210_PLL_FS_16000 (0x5 << 0)
137#define DA7210_PLL_FS_22050 (0x6 << 0)
138#define DA7210_PLL_FS_24000 (0x7 << 0)
139#define DA7210_PLL_FS_32000 (0x9 << 0)
140#define DA7210_PLL_FS_44100 (0xA << 0)
141#define DA7210_PLL_FS_48000 (0xB << 0)
142#define DA7210_PLL_FS_88200 (0xE << 0)
143#define DA7210_PLL_FS_96000 (0xF << 0)
144#define DA7210_PLL_EN (0x1 << 7)
128 145
129#define DA7210_VERSION "0.0.1" 146#define DA7210_VERSION "0.0.1"
130 147
@@ -165,7 +182,7 @@ static const u8 da7210_reg[] = {
165static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg) 182static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
166{ 183{
167 u8 *cache = codec->reg_cache; 184 u8 *cache = codec->reg_cache;
168 BUG_ON(reg > ARRAY_SIZE(da7210_reg)); 185 BUG_ON(reg >= ARRAY_SIZE(da7210_reg));
169 return cache[reg]; 186 return cache[reg];
170} 187}
171 188
@@ -242,7 +259,8 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
242 struct snd_soc_device *socdev = rtd->socdev; 259 struct snd_soc_device *socdev = rtd->socdev;
243 struct snd_soc_codec *codec = socdev->card->codec; 260 struct snd_soc_codec *codec = socdev->card->codec;
244 u32 dai_cfg1; 261 u32 dai_cfg1;
245 u32 reg, mask; 262 u32 hpf_reg, hpf_mask, hpf_value;
263 u32 fs, bypass;
246 264
247 /* set DAI source to Left and Right ADC */ 265 /* set DAI source to Left and Right ADC */
248 da7210_write(codec, DA7210_DAI_SRC_SEL, 266 da7210_write(codec, DA7210_DAI_SRC_SEL,
@@ -266,25 +284,84 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
266 284
267 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); 285 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
268 286
269 /* FIXME 287 hpf_reg = (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) ?
270 * 288 DA7210_DAC_HPF : DA7210_ADC_HPF;
271 * It support 48K only now 289
272 */
273 switch (params_rate(params)) { 290 switch (params_rate(params)) {
291 case 8000:
292 fs = DA7210_PLL_FS_8000;
293 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
294 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
295 bypass = DA7210_PLL_BYP;
296 break;
297 case 11025:
298 fs = DA7210_PLL_FS_11025;
299 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
300 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
301 bypass = 0;
302 break;
303 case 12000:
304 fs = DA7210_PLL_FS_12000;
305 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
306 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
307 bypass = DA7210_PLL_BYP;
308 break;
309 case 16000:
310 fs = DA7210_PLL_FS_16000;
311 hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN;
312 hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN;
313 bypass = DA7210_PLL_BYP;
314 break;
315 case 22050:
316 fs = DA7210_PLL_FS_22050;
317 hpf_mask = DA7210_VOICE_EN;
318 hpf_value = 0;
319 bypass = 0;
320 break;
321 case 32000:
322 fs = DA7210_PLL_FS_32000;
323 hpf_mask = DA7210_VOICE_EN;
324 hpf_value = 0;
325 bypass = DA7210_PLL_BYP;
326 break;
327 case 44100:
328 fs = DA7210_PLL_FS_44100;
329 hpf_mask = DA7210_VOICE_EN;
330 hpf_value = 0;
331 bypass = 0;
332 break;
274 case 48000: 333 case 48000:
275 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { 334 fs = DA7210_PLL_FS_48000;
276 reg = DA7210_DAC_HPF; 335 hpf_mask = DA7210_VOICE_EN;
277 mask = DA7210_DAC_VOICE_EN; 336 hpf_value = 0;
278 } else { 337 bypass = DA7210_PLL_BYP;
279 reg = DA7210_ADC_HPF; 338 break;
280 mask = DA7210_ADC_VOICE_EN; 339 case 88200:
281 } 340 fs = DA7210_PLL_FS_88200;
341 hpf_mask = DA7210_VOICE_EN;
342 hpf_value = 0;
343 bypass = 0;
344 break;
345 case 96000:
346 fs = DA7210_PLL_FS_96000;
347 hpf_mask = DA7210_VOICE_EN;
348 hpf_value = 0;
349 bypass = DA7210_PLL_BYP;
282 break; 350 break;
283 default: 351 default:
284 return -EINVAL; 352 return -EINVAL;
285 } 353 }
286 354
287 snd_soc_update_bits(codec, reg, mask, 0); 355 /* Disable active mode */
356 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
357
358 snd_soc_update_bits(codec, hpf_reg, hpf_mask, hpf_value);
359 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
360 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
361
362 /* Enable active mode */
363 snd_soc_update_bits(codec, DA7210_STARTUP1,
364 DA7210_SC_MST_EN, DA7210_SC_MST_EN);
288 365
289 return 0; 366 return 0;
290} 367}
@@ -362,6 +439,7 @@ struct snd_soc_dai da7210_dai = {
362 .formats = DA7210_FORMATS, 439 .formats = DA7210_FORMATS,
363 }, 440 },
364 .ops = &da7210_dai_ops, 441 .ops = &da7210_dai_ops,
442 .symmetric_rates = 1,
365}; 443};
366EXPORT_SYMBOL_GPL(da7210_dai); 444EXPORT_SYMBOL_GPL(da7210_dai);
367 445
@@ -383,7 +461,7 @@ static int da7210_init(struct da7210_priv *da7210)
383 INIT_LIST_HEAD(&codec->dapm_widgets); 461 INIT_LIST_HEAD(&codec->dapm_widgets);
384 INIT_LIST_HEAD(&codec->dapm_paths); 462 INIT_LIST_HEAD(&codec->dapm_paths);
385 463
386 codec->private_data = da7210; 464 snd_soc_codec_set_drvdata(codec, da7210);
387 codec->name = "DA7210"; 465 codec->name = "DA7210";
388 codec->owner = THIS_MODULE; 466 codec->owner = THIS_MODULE;
389 codec->read = da7210_read; 467 codec->read = da7210_read;
@@ -416,9 +494,23 @@ static int da7210_init(struct da7210_priv *da7210)
416 /* FIXME 494 /* FIXME
417 * 495 *
418 * This driver use fixed value here 496 * This driver use fixed value here
497 * And below settings expects MCLK = 12.288MHz
498 *
499 * When you select different MCLK, please check...
500 * DA7210_PLL_DIV1 val
501 * DA7210_PLL_DIV2 val
502 * DA7210_PLL_DIV3 val
503 * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
419 */ 504 */
420 505
421 /* 506 /*
507 * make sure that DA7210 use bypass mode before start up
508 */
509 da7210_write(codec, DA7210_STARTUP1, 0);
510 da7210_write(codec, DA7210_PLL_DIV3,
511 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
512
513 /*
422 * ADC settings 514 * ADC settings
423 */ 515 */
424 516
@@ -454,9 +546,28 @@ static int da7210_init(struct da7210_priv *da7210)
454 /* Diable PLL and bypass it */ 546 /* Diable PLL and bypass it */
455 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); 547 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
456 548
457 /* Bypass PLL and set MCLK freq rang to 10-20MHz */ 549 /*
458 da7210_write(codec, DA7210_PLL_DIV3, 550 * If 48kHz sound came, it use bypass mode,
551 * and when it is 44.1kHz, it use PLL.
552 *
553 * This time, this driver sets PLL always ON
554 * and controls bypass/PLL mode by switching
555 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
556 * see da7210_hw_params
557 */
558 da7210_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
559 da7210_write(codec, DA7210_PLL_DIV2, 0x99);
560 da7210_write(codec, DA7210_PLL_DIV3, 0x0A |
459 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); 561 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
562 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
563
564 /* As suggested by Dialog */
565 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */
566 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0xB4);
567 da7210_write(codec, DA7210_A_PLL1, 0x01);
568 da7210_write(codec, DA7210_A_CP_MODE, 0x7C);
569 da7210_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */
570 da7210_write(codec, DA7210_A_TEST_UNLOCK, 0x00);
460 571
461 /* Activate all enabled subsystem */ 572 /* Activate all enabled subsystem */
462 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 573 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 29d0906a924a..b47ed4f6ab20 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -140,6 +140,7 @@ SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0),
140SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1), 140SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1),
141 141
142SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0), 142SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0),
143SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 7, 1, 0),
143SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1), 144SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1),
144 145
145SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1), 146SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1),
@@ -277,7 +278,7 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 278 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_device *socdev = rtd->socdev; 279 struct snd_soc_device *socdev = rtd->socdev;
279 struct snd_soc_codec *codec = socdev->card->codec; 280 struct snd_soc_codec *codec = socdev->card->codec;
280 struct ssm2602_priv *ssm2602 = codec->private_data; 281 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
281 struct i2c_client *i2c = codec->control_data; 282 struct i2c_client *i2c = codec->control_data;
282 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 283 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
283 int i = get_coeff(ssm2602->sysclk, params_rate(params)); 284 int i = get_coeff(ssm2602->sysclk, params_rate(params));
@@ -322,7 +323,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
322 struct snd_soc_pcm_runtime *rtd = substream->private_data; 323 struct snd_soc_pcm_runtime *rtd = substream->private_data;
323 struct snd_soc_device *socdev = rtd->socdev; 324 struct snd_soc_device *socdev = rtd->socdev;
324 struct snd_soc_codec *codec = socdev->card->codec; 325 struct snd_soc_codec *codec = socdev->card->codec;
325 struct ssm2602_priv *ssm2602 = codec->private_data; 326 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
326 struct i2c_client *i2c = codec->control_data; 327 struct i2c_client *i2c = codec->control_data;
327 struct snd_pcm_runtime *master_runtime; 328 struct snd_pcm_runtime *master_runtime;
328 329
@@ -373,7 +374,7 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
373 struct snd_soc_pcm_runtime *rtd = substream->private_data; 374 struct snd_soc_pcm_runtime *rtd = substream->private_data;
374 struct snd_soc_device *socdev = rtd->socdev; 375 struct snd_soc_device *socdev = rtd->socdev;
375 struct snd_soc_codec *codec = socdev->card->codec; 376 struct snd_soc_codec *codec = socdev->card->codec;
376 struct ssm2602_priv *ssm2602 = codec->private_data; 377 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
377 378
378 /* deactivate */ 379 /* deactivate */
379 if (!codec->active) 380 if (!codec->active)
@@ -401,7 +402,7 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
401 int clk_id, unsigned int freq, int dir) 402 int clk_id, unsigned int freq, int dir)
402{ 403{
403 struct snd_soc_codec *codec = codec_dai->codec; 404 struct snd_soc_codec *codec = codec_dai->codec;
404 struct ssm2602_priv *ssm2602 = codec->private_data; 405 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
405 switch (freq) { 406 switch (freq) {
406 case 11289600: 407 case 11289600:
407 case 12000000: 408 case 12000000:
@@ -559,7 +560,6 @@ static int ssm2602_resume(struct platform_device *pdev)
559 codec->hw_write(codec->control_data, data, 2); 560 codec->hw_write(codec->control_data, data, 2);
560 } 561 }
561 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 562 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
562 ssm2602_set_bias_level(codec, codec->suspend_bias_level);
563 return 0; 563 return 0;
564} 564}
565 565
@@ -605,8 +605,7 @@ static int ssm2602_init(struct snd_soc_device *socdev)
605 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V); 605 reg = ssm2602_read_reg_cache(codec, SSM2602_ROUT1V);
606 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH); 606 ssm2602_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH);
607 /*select Line in as default input*/ 607 /*select Line in as default input*/
608 ssm2602_write(codec, SSM2602_APANA, 608 ssm2602_write(codec, SSM2602_APANA, APANA_SELECT_DAC |
609 APANA_ENABLE_MIC_BOOST2 | APANA_SELECT_DAC |
610 APANA_ENABLE_MIC_BOOST); 609 APANA_ENABLE_MIC_BOOST);
611 ssm2602_write(codec, SSM2602_PWR, 0); 610 ssm2602_write(codec, SSM2602_PWR, 0);
612 611
@@ -727,7 +726,7 @@ static int ssm2602_probe(struct platform_device *pdev)
727 return -ENOMEM; 726 return -ENOMEM;
728 } 727 }
729 728
730 codec->private_data = ssm2602; 729 snd_soc_codec_set_drvdata(codec, ssm2602);
731 socdev->card->codec = codec; 730 socdev->card->codec = codec;
732 mutex_init(&codec->mutex); 731 mutex_init(&codec->mutex);
733 INIT_LIST_HEAD(&codec->dapm_widgets); 732 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -760,7 +759,7 @@ static int ssm2602_remove(struct platform_device *pdev)
760 i2c_unregister_device(codec->control_data); 759 i2c_unregister_device(codec->control_data);
761 i2c_del_driver(&ssm2602_i2c_driver); 760 i2c_del_driver(&ssm2602_i2c_driver);
762#endif 761#endif
763 kfree(codec->private_data); 762 kfree(snd_soc_codec_get_drvdata(codec));
764 kfree(codec); 763 kfree(codec);
765 764
766 return 0; 765 return 0;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 3293629dcb3b..ee86568545c2 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -289,9 +289,6 @@ reset:
289 } 289 }
290 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 290 stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
291 291
292 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
293 stac9766_set_bias_level(codec, SND_SOC_BIAS_ON);
294
295 return 0; 292 return 0;
296} 293}
297 294
@@ -410,7 +407,7 @@ reset_err:
410pcm_err: 407pcm_err:
411 snd_soc_free_ac97_codec(codec); 408 snd_soc_free_ac97_codec(codec);
412codec_err: 409codec_err:
413 kfree(codec->private_data); 410 kfree(snd_soc_codec_get_drvdata(codec));
414cache_err: 411cache_err:
415 kfree(socdev->card->codec); 412 kfree(socdev->card->codec);
416 socdev->card->codec = NULL; 413 socdev->card->codec = NULL;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 776b79cde904..b0bae3508b29 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -634,7 +634,6 @@ static int tlv320aic23_resume(struct platform_device *pdev)
634 } 634 }
635 635
636 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 636 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
637 tlv320aic23_set_bias_level(codec, codec->suspend_bias_level);
638 637
639 return 0; 638 return 0;
640} 639}
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index b5b7d6a03844..f0e00fd4b435 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -49,7 +49,7 @@ struct aic26 {
49static unsigned int aic26_reg_read(struct snd_soc_codec *codec, 49static unsigned int aic26_reg_read(struct snd_soc_codec *codec,
50 unsigned int reg) 50 unsigned int reg)
51{ 51{
52 struct aic26 *aic26 = codec->private_data; 52 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
53 u16 *cache = codec->reg_cache; 53 u16 *cache = codec->reg_cache;
54 u16 cmd, value; 54 u16 cmd, value;
55 u8 buffer[2]; 55 u8 buffer[2];
@@ -93,7 +93,7 @@ static unsigned int aic26_reg_read_cache(struct snd_soc_codec *codec,
93static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg, 93static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
94 unsigned int value) 94 unsigned int value)
95{ 95{
96 struct aic26 *aic26 = codec->private_data; 96 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
97 u16 *cache = codec->reg_cache; 97 u16 *cache = codec->reg_cache;
98 u16 cmd; 98 u16 cmd;
99 u8 buffer[4]; 99 u8 buffer[4];
@@ -132,7 +132,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 132 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_soc_device *socdev = rtd->socdev; 133 struct snd_soc_device *socdev = rtd->socdev;
134 struct snd_soc_codec *codec = socdev->card->codec; 134 struct snd_soc_codec *codec = socdev->card->codec;
135 struct aic26 *aic26 = codec->private_data; 135 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
136 int fsref, divisor, wlen, pval, jval, dval, qval; 136 int fsref, divisor, wlen, pval, jval, dval, qval;
137 u16 reg; 137 u16 reg;
138 138
@@ -199,7 +199,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
199static int aic26_mute(struct snd_soc_dai *dai, int mute) 199static int aic26_mute(struct snd_soc_dai *dai, int mute)
200{ 200{
201 struct snd_soc_codec *codec = dai->codec; 201 struct snd_soc_codec *codec = dai->codec;
202 struct aic26 *aic26 = codec->private_data; 202 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
203 u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN); 203 u16 reg = aic26_reg_read_cache(codec, AIC26_REG_DAC_GAIN);
204 204
205 dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n", 205 dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n",
@@ -218,7 +218,7 @@ static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
218 int clk_id, unsigned int freq, int dir) 218 int clk_id, unsigned int freq, int dir)
219{ 219{
220 struct snd_soc_codec *codec = codec_dai->codec; 220 struct snd_soc_codec *codec = codec_dai->codec;
221 struct aic26 *aic26 = codec->private_data; 221 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
222 222
223 dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i," 223 dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i,"
224 " freq=%i, dir=%i)\n", 224 " freq=%i, dir=%i)\n",
@@ -235,7 +235,7 @@ static int aic26_set_sysclk(struct snd_soc_dai *codec_dai,
235static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 235static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
236{ 236{
237 struct snd_soc_codec *codec = codec_dai->codec; 237 struct snd_soc_codec *codec = codec_dai->codec;
238 struct aic26 *aic26 = codec->private_data; 238 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
239 239
240 dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n", 240 dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n",
241 codec_dai, fmt); 241 codec_dai, fmt);
@@ -431,7 +431,7 @@ static int aic26_spi_probe(struct spi_device *spi)
431 /* Setup what we can in the codec structure so that the register 431 /* Setup what we can in the codec structure so that the register
432 * access functions will work as expected. More will be filled 432 * access functions will work as expected. More will be filled
433 * out when it is probed by the SoC CODEC part of this driver */ 433 * out when it is probed by the SoC CODEC part of this driver */
434 aic26->codec.private_data = aic26; 434 snd_soc_codec_set_drvdata(&aic26->codec, aic26);
435 aic26->codec.name = "aic26"; 435 aic26->codec.name = "aic26";
436 aic26->codec.owner = THIS_MODULE; 436 aic26->codec.owner = THIS_MODULE;
437 aic26->codec.dai = &aic26_dai; 437 aic26->codec.dai = &aic26_dai;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 4a6d56c3fed9..71a69908ccf6 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -38,6 +38,8 @@
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/pm.h> 39#include <linux/pm.h>
40#include <linux/i2c.h> 40#include <linux/i2c.h>
41#include <linux/gpio.h>
42#include <linux/regulator/consumer.h>
41#include <linux/platform_device.h> 43#include <linux/platform_device.h>
42#include <linux/slab.h> 44#include <linux/slab.h>
43#include <sound/core.h> 45#include <sound/core.h>
@@ -47,16 +49,25 @@
47#include <sound/soc-dapm.h> 49#include <sound/soc-dapm.h>
48#include <sound/initval.h> 50#include <sound/initval.h>
49#include <sound/tlv.h> 51#include <sound/tlv.h>
52#include <sound/tlv320aic3x.h>
50 53
51#include "tlv320aic3x.h" 54#include "tlv320aic3x.h"
52 55
53#define AIC3X_VERSION "0.2" 56#define AIC3X_NUM_SUPPLIES 4
57static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
58 "IOVDD", /* I/O Voltage */
59 "DVDD", /* Digital Core Voltage */
60 "AVDD", /* Analog DAC Voltage */
61 "DRVDD", /* ADC Analog and Output Driver Voltage */
62};
54 63
55/* codec private data */ 64/* codec private data */
56struct aic3x_priv { 65struct aic3x_priv {
57 struct snd_soc_codec codec; 66 struct snd_soc_codec codec;
67 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
58 unsigned int sysclk; 68 unsigned int sysclk;
59 int master; 69 int master;
70 int gpio_reset;
60}; 71};
61 72
62/* 73/*
@@ -764,7 +775,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
764 struct snd_soc_pcm_runtime *rtd = substream->private_data; 775 struct snd_soc_pcm_runtime *rtd = substream->private_data;
765 struct snd_soc_device *socdev = rtd->socdev; 776 struct snd_soc_device *socdev = rtd->socdev;
766 struct snd_soc_codec *codec = socdev->card->codec; 777 struct snd_soc_codec *codec = socdev->card->codec;
767 struct aic3x_priv *aic3x = codec->private_data; 778 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
768 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 779 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
769 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 780 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
770 u16 d, pll_d = 1; 781 u16 d, pll_d = 1;
@@ -931,7 +942,7 @@ static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
931 int clk_id, unsigned int freq, int dir) 942 int clk_id, unsigned int freq, int dir)
932{ 943{
933 struct snd_soc_codec *codec = codec_dai->codec; 944 struct snd_soc_codec *codec = codec_dai->codec;
934 struct aic3x_priv *aic3x = codec->private_data; 945 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
935 946
936 aic3x->sysclk = freq; 947 aic3x->sysclk = freq;
937 return 0; 948 return 0;
@@ -941,7 +952,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
941 unsigned int fmt) 952 unsigned int fmt)
942{ 953{
943 struct snd_soc_codec *codec = codec_dai->codec; 954 struct snd_soc_codec *codec = codec_dai->codec;
944 struct aic3x_priv *aic3x = codec->private_data; 955 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
945 u8 iface_areg, iface_breg; 956 u8 iface_areg, iface_breg;
946 int delay = 0; 957 int delay = 0;
947 958
@@ -995,12 +1006,13 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
995static int aic3x_set_bias_level(struct snd_soc_codec *codec, 1006static int aic3x_set_bias_level(struct snd_soc_codec *codec,
996 enum snd_soc_bias_level level) 1007 enum snd_soc_bias_level level)
997{ 1008{
998 struct aic3x_priv *aic3x = codec->private_data; 1009 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
999 u8 reg; 1010 u8 reg;
1000 1011
1001 switch (level) { 1012 switch (level) {
1002 case SND_SOC_BIAS_ON: 1013 case SND_SOC_BIAS_ON:
1003 /* all power is driven by DAPM system */ 1014 break;
1015 case SND_SOC_BIAS_PREPARE:
1004 if (aic3x->master) { 1016 if (aic3x->master) {
1005 /* enable pll */ 1017 /* enable pll */
1006 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 1018 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
@@ -1008,48 +1020,9 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1008 reg | PLL_ENABLE); 1020 reg | PLL_ENABLE);
1009 } 1021 }
1010 break; 1022 break;
1011 case SND_SOC_BIAS_PREPARE:
1012 break;
1013 case SND_SOC_BIAS_STANDBY: 1023 case SND_SOC_BIAS_STANDBY:
1014 /* 1024 /* fall through and disable pll */
1015 * all power is driven by DAPM system,
1016 * so output power is safe if bypass was set
1017 */
1018 if (aic3x->master) {
1019 /* disable pll */
1020 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
1021 aic3x_write(codec, AIC3X_PLL_PROGA_REG,
1022 reg & ~PLL_ENABLE);
1023 }
1024 break;
1025 case SND_SOC_BIAS_OFF: 1025 case SND_SOC_BIAS_OFF:
1026 /* force all power off */
1027 reg = aic3x_read_reg_cache(codec, LINE1L_2_LADC_CTRL);
1028 aic3x_write(codec, LINE1L_2_LADC_CTRL, reg & ~LADC_PWR_ON);
1029 reg = aic3x_read_reg_cache(codec, LINE1R_2_RADC_CTRL);
1030 aic3x_write(codec, LINE1R_2_RADC_CTRL, reg & ~RADC_PWR_ON);
1031
1032 reg = aic3x_read_reg_cache(codec, DAC_PWR);
1033 aic3x_write(codec, DAC_PWR, reg & ~(LDAC_PWR_ON | RDAC_PWR_ON));
1034
1035 reg = aic3x_read_reg_cache(codec, HPLOUT_CTRL);
1036 aic3x_write(codec, HPLOUT_CTRL, reg & ~HPLOUT_PWR_ON);
1037 reg = aic3x_read_reg_cache(codec, HPROUT_CTRL);
1038 aic3x_write(codec, HPROUT_CTRL, reg & ~HPROUT_PWR_ON);
1039
1040 reg = aic3x_read_reg_cache(codec, HPLCOM_CTRL);
1041 aic3x_write(codec, HPLCOM_CTRL, reg & ~HPLCOM_PWR_ON);
1042 reg = aic3x_read_reg_cache(codec, HPRCOM_CTRL);
1043 aic3x_write(codec, HPRCOM_CTRL, reg & ~HPRCOM_PWR_ON);
1044
1045 reg = aic3x_read_reg_cache(codec, MONOLOPM_CTRL);
1046 aic3x_write(codec, MONOLOPM_CTRL, reg & ~MONOLOPM_PWR_ON);
1047
1048 reg = aic3x_read_reg_cache(codec, LLOPM_CTRL);
1049 aic3x_write(codec, LLOPM_CTRL, reg & ~LLOPM_PWR_ON);
1050 reg = aic3x_read_reg_cache(codec, RLOPM_CTRL);
1051 aic3x_write(codec, RLOPM_CTRL, reg & ~RLOPM_PWR_ON);
1052
1053 if (aic3x->master) { 1026 if (aic3x->master) {
1054 /* disable pll */ 1027 /* disable pll */
1055 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 1028 reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
@@ -1171,7 +1144,7 @@ static int aic3x_resume(struct platform_device *pdev)
1171 codec->hw_write(codec->control_data, data, 2); 1144 codec->hw_write(codec->control_data, data, 2);
1172 } 1145 }
1173 1146
1174 aic3x_set_bias_level(codec, codec->suspend_bias_level); 1147 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1175 1148
1176 return 0; 1149 return 0;
1177} 1150}
@@ -1309,6 +1282,13 @@ static int aic3x_unregister(struct aic3x_priv *aic3x)
1309 snd_soc_unregister_dai(&aic3x_dai); 1282 snd_soc_unregister_dai(&aic3x_dai);
1310 snd_soc_unregister_codec(&aic3x->codec); 1283 snd_soc_unregister_codec(&aic3x->codec);
1311 1284
1285 if (aic3x->gpio_reset >= 0) {
1286 gpio_set_value(aic3x->gpio_reset, 0);
1287 gpio_free(aic3x->gpio_reset);
1288 }
1289 regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1290 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1291
1312 kfree(aic3x); 1292 kfree(aic3x);
1313 aic3x_codec = NULL; 1293 aic3x_codec = NULL;
1314 1294
@@ -1330,6 +1310,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1330{ 1310{
1331 struct snd_soc_codec *codec; 1311 struct snd_soc_codec *codec;
1332 struct aic3x_priv *aic3x; 1312 struct aic3x_priv *aic3x;
1313 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1314 int ret, i;
1333 1315
1334 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1316 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
1335 if (aic3x == NULL) { 1317 if (aic3x == NULL) {
@@ -1339,13 +1321,53 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
1339 1321
1340 codec = &aic3x->codec; 1322 codec = &aic3x->codec;
1341 codec->dev = &i2c->dev; 1323 codec->dev = &i2c->dev;
1342 codec->private_data = aic3x; 1324 snd_soc_codec_set_drvdata(codec, aic3x);
1343 codec->control_data = i2c; 1325 codec->control_data = i2c;
1344 codec->hw_write = (hw_write_t) i2c_master_send; 1326 codec->hw_write = (hw_write_t) i2c_master_send;
1345 1327
1346 i2c_set_clientdata(i2c, aic3x); 1328 i2c_set_clientdata(i2c, aic3x);
1347 1329
1330 aic3x->gpio_reset = -1;
1331 if (pdata && pdata->gpio_reset >= 0) {
1332 ret = gpio_request(pdata->gpio_reset, "tlv320aic3x reset");
1333 if (ret != 0)
1334 goto err_gpio;
1335 aic3x->gpio_reset = pdata->gpio_reset;
1336 gpio_direction_output(aic3x->gpio_reset, 0);
1337 }
1338
1339 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1340 aic3x->supplies[i].supply = aic3x_supply_names[i];
1341
1342 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
1343 aic3x->supplies);
1344 if (ret != 0) {
1345 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1346 goto err_get;
1347 }
1348
1349 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
1350 aic3x->supplies);
1351 if (ret != 0) {
1352 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1353 goto err_enable;
1354 }
1355
1356 if (aic3x->gpio_reset >= 0) {
1357 udelay(1);
1358 gpio_set_value(aic3x->gpio_reset, 1);
1359 }
1360
1348 return aic3x_register(codec); 1361 return aic3x_register(codec);
1362
1363err_enable:
1364 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1365err_get:
1366 if (aic3x->gpio_reset >= 0)
1367 gpio_free(aic3x->gpio_reset);
1368err_gpio:
1369 kfree(aic3x);
1370 return ret;
1349} 1371}
1350 1372
1351static int aic3x_i2c_remove(struct i2c_client *client) 1373static int aic3x_i2c_remove(struct i2c_client *client)
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index d1e0e81ef30c..65adc77eada1 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -51,6 +51,20 @@
51 51
52#define LATENCY_TIME_MS 20 52#define LATENCY_TIME_MS 20
53 53
54#define MODE7_LTHR 10
55#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10)
56
57#define BURST_BASEFREQ_HZ 49152000
58
59#define SAMPLES_TO_US(rate, samples) \
60 (1000000000 / ((rate * 1000) / samples))
61
62#define US_TO_SAMPLES(rate, us) \
63 (rate / (1000000 / us))
64
65static void dac33_calculate_times(struct snd_pcm_substream *substream);
66static int dac33_prepare_chip(struct snd_pcm_substream *substream);
67
54static struct snd_soc_codec *tlv320dac33_codec; 68static struct snd_soc_codec *tlv320dac33_codec;
55 69
56enum dac33_state { 70enum dac33_state {
@@ -80,6 +94,7 @@ struct tlv320dac33_priv {
80 struct work_struct work; 94 struct work_struct work;
81 struct snd_soc_codec codec; 95 struct snd_soc_codec codec;
82 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES]; 96 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
97 struct snd_pcm_substream *substream;
83 int power_gpio; 98 int power_gpio;
84 int chip_power; 99 int chip_power;
85 int irq; 100 int irq;
@@ -93,6 +108,17 @@ struct tlv320dac33_priv {
93 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ 108 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
94 unsigned int nsample; /* burst read amount from host */ 109 unsigned int nsample; /* burst read amount from host */
95 u8 burst_bclkdiv; /* BCLK divider value in burst mode */ 110 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
111 unsigned int burst_rate; /* Interface speed in Burst modes */
112
113 int keep_bclk; /* Keep the BCLK continuously running
114 * in FIFO modes */
115 spinlock_t lock;
116 unsigned long long t_stamp1; /* Time stamp for FIFO modes to */
117 unsigned long long t_stamp2; /* calculate the FIFO caused delay */
118
119 unsigned int mode1_us_burst; /* Time to burst read n number of
120 * samples */
121 unsigned int mode7_us_to_lthr; /* Time to reach lthr from uthr */
96 122
97 enum dac33_state state; 123 enum dac33_state state;
98}; 124};
@@ -166,7 +192,7 @@ static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
166static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, 192static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
167 u8 *value) 193 u8 *value)
168{ 194{
169 struct tlv320dac33_priv *dac33 = codec->private_data; 195 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
170 int val; 196 int val;
171 197
172 *value = reg & 0xff; 198 *value = reg & 0xff;
@@ -191,7 +217,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
191static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, 217static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
192 unsigned int value) 218 unsigned int value)
193{ 219{
194 struct tlv320dac33_priv *dac33 = codec->private_data; 220 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
195 u8 data[2]; 221 u8 data[2];
196 int ret = 0; 222 int ret = 0;
197 223
@@ -218,7 +244,7 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
218static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg, 244static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
219 unsigned int value) 245 unsigned int value)
220{ 246{
221 struct tlv320dac33_priv *dac33 = codec->private_data; 247 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
222 int ret; 248 int ret;
223 249
224 mutex_lock(&dac33->mutex); 250 mutex_lock(&dac33->mutex);
@@ -232,7 +258,7 @@ static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
232static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg, 258static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
233 unsigned int value) 259 unsigned int value)
234{ 260{
235 struct tlv320dac33_priv *dac33 = codec->private_data; 261 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
236 u8 data[3]; 262 u8 data[3];
237 int ret = 0; 263 int ret = 0;
238 264
@@ -262,45 +288,47 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
262 return ret; 288 return ret;
263} 289}
264 290
265static void dac33_restore_regs(struct snd_soc_codec *codec) 291static void dac33_init_chip(struct snd_soc_codec *codec)
266{ 292{
267 struct tlv320dac33_priv *dac33 = codec->private_data; 293 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
268 u8 *cache = codec->reg_cache;
269 u8 data[2];
270 int i, ret;
271 294
272 if (!dac33->chip_power) 295 if (unlikely(!dac33->chip_power))
273 return; 296 return;
274 297
275 for (i = DAC33_PWR_CTRL; i <= DAC33_INTP_CTRL_B; i++) { 298 /* 44-46: DAC Control Registers */
276 data[0] = i; 299 /* A : DAC sample rate Fsref/1.5 */
277 data[1] = cache[i]; 300 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
278 /* Skip the read only registers */ 301 /* B : DAC src=normal, not muted */
279 if ((i >= DAC33_INT_OSC_STATUS && 302 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
280 i <= DAC33_INT_OSC_FREQ_RAT_READ_B) || 303 DAC33_DACSRCL_LEFT);
281 (i >= DAC33_FIFO_WPTR_MSB && i <= DAC33_FIFO_IRQ_FLAG) || 304 /* C : (defaults) */
282 i == DAC33_DAC_STATUS_FLAGS || 305 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
283 i == DAC33_SRC_EST_REF_CLK_RATIO_A || 306
284 i == DAC33_SRC_EST_REF_CLK_RATIO_B) 307 /* 73 : volume soft stepping control,
285 continue; 308 clock source = internal osc (?) */
286 ret = codec->hw_write(codec->control_data, data, 2); 309 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
287 if (ret != 2) 310
288 dev_err(codec->dev, "Write failed (%d)\n", ret); 311 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
289 } 312
290 for (i = DAC33_LDAC_PWR_CTRL; i <= DAC33_LINEL_TO_LLO_VOL; i++) { 313 /* Restore only selected registers (gains mostly) */
291 data[0] = i; 314 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
292 data[1] = cache[i]; 315 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
293 ret = codec->hw_write(codec->control_data, data, 2); 316 dac33_write(codec, DAC33_RDAC_DIG_VOL_CTRL,
294 if (ret != 2) 317 dac33_read_reg_cache(codec, DAC33_RDAC_DIG_VOL_CTRL));
295 dev_err(codec->dev, "Write failed (%d)\n", ret); 318
296 } 319 dac33_write(codec, DAC33_LINEL_TO_LLO_VOL,
297 for (i = DAC33_LINER_TO_RLO_VOL; i <= DAC33_OSC_TRIM; i++) { 320 dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL));
298 data[0] = i; 321 dac33_write(codec, DAC33_LINER_TO_RLO_VOL,
299 data[1] = cache[i]; 322 dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
300 ret = codec->hw_write(codec->control_data, data, 2); 323}
301 if (ret != 2) 324
302 dev_err(codec->dev, "Write failed (%d)\n", ret); 325static inline void dac33_read_id(struct snd_soc_codec *codec)
303 } 326{
327 u8 reg;
328
329 dac33_read(codec, DAC33_DEVICE_ID_MSB, &reg);
330 dac33_read(codec, DAC33_DEVICE_ID_LSB, &reg);
331 dac33_read(codec, DAC33_DEVICE_REV_ID, &reg);
304} 332}
305 333
306static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) 334static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
@@ -311,16 +339,25 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
311 if (power) 339 if (power)
312 reg |= DAC33_PDNALLB; 340 reg |= DAC33_PDNALLB;
313 else 341 else
314 reg &= ~DAC33_PDNALLB; 342 reg &= ~(DAC33_PDNALLB | DAC33_OSCPDNB |
343 DAC33_DACRPDNB | DAC33_DACLPDNB);
315 dac33_write(codec, DAC33_PWR_CTRL, reg); 344 dac33_write(codec, DAC33_PWR_CTRL, reg);
316} 345}
317 346
318static int dac33_hard_power(struct snd_soc_codec *codec, int power) 347static int dac33_hard_power(struct snd_soc_codec *codec, int power)
319{ 348{
320 struct tlv320dac33_priv *dac33 = codec->private_data; 349 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
321 int ret; 350 int ret = 0;
322 351
323 mutex_lock(&dac33->mutex); 352 mutex_lock(&dac33->mutex);
353
354 /* Safety check */
355 if (unlikely(power == dac33->chip_power)) {
356 dev_dbg(codec->dev, "Trying to set the same power state: %s\n",
357 power ? "ON" : "OFF");
358 goto exit;
359 }
360
324 if (power) { 361 if (power) {
325 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies), 362 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
326 dac33->supplies); 363 dac33->supplies);
@@ -334,11 +371,6 @@ static int dac33_hard_power(struct snd_soc_codec *codec, int power)
334 gpio_set_value(dac33->power_gpio, 1); 371 gpio_set_value(dac33->power_gpio, 1);
335 372
336 dac33->chip_power = 1; 373 dac33->chip_power = 1;
337
338 /* Restore registers */
339 dac33_restore_regs(codec);
340
341 dac33_soft_power(codec, 1);
342 } else { 374 } else {
343 dac33_soft_power(codec, 0); 375 dac33_soft_power(codec, 0);
344 if (dac33->power_gpio >= 0) 376 if (dac33->power_gpio >= 0)
@@ -360,11 +392,27 @@ exit:
360 return ret; 392 return ret;
361} 393}
362 394
395static int playback_event(struct snd_soc_dapm_widget *w,
396 struct snd_kcontrol *kcontrol, int event)
397{
398 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
399
400 switch (event) {
401 case SND_SOC_DAPM_PRE_PMU:
402 if (likely(dac33->substream)) {
403 dac33_calculate_times(dac33->substream);
404 dac33_prepare_chip(dac33->substream);
405 }
406 break;
407 }
408 return 0;
409}
410
363static int dac33_get_nsample(struct snd_kcontrol *kcontrol, 411static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
364 struct snd_ctl_elem_value *ucontrol) 412 struct snd_ctl_elem_value *ucontrol)
365{ 413{
366 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 414 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
367 struct tlv320dac33_priv *dac33 = codec->private_data; 415 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
368 416
369 ucontrol->value.integer.value[0] = dac33->nsample; 417 ucontrol->value.integer.value[0] = dac33->nsample;
370 418
@@ -375,17 +423,21 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol) 423 struct snd_ctl_elem_value *ucontrol)
376{ 424{
377 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 425 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
378 struct tlv320dac33_priv *dac33 = codec->private_data; 426 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
379 int ret = 0; 427 int ret = 0;
380 428
381 if (dac33->nsample == ucontrol->value.integer.value[0]) 429 if (dac33->nsample == ucontrol->value.integer.value[0])
382 return 0; 430 return 0;
383 431
384 if (ucontrol->value.integer.value[0] < dac33->nsample_min || 432 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
385 ucontrol->value.integer.value[0] > dac33->nsample_max) 433 ucontrol->value.integer.value[0] > dac33->nsample_max) {
386 ret = -EINVAL; 434 ret = -EINVAL;
387 else 435 } else {
388 dac33->nsample = ucontrol->value.integer.value[0]; 436 dac33->nsample = ucontrol->value.integer.value[0];
437 /* Re calculate the burst time */
438 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
439 dac33->nsample);
440 }
389 441
390 return ret; 442 return ret;
391} 443}
@@ -394,7 +446,7 @@ static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol) 446 struct snd_ctl_elem_value *ucontrol)
395{ 447{
396 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 448 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct tlv320dac33_priv *dac33 = codec->private_data; 449 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
398 450
399 ucontrol->value.integer.value[0] = dac33->fifo_mode; 451 ucontrol->value.integer.value[0] = dac33->fifo_mode;
400 452
@@ -405,7 +457,7 @@ static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
405 struct snd_ctl_elem_value *ucontrol) 457 struct snd_ctl_elem_value *ucontrol)
406{ 458{
407 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 459 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
408 struct tlv320dac33_priv *dac33 = codec->private_data; 460 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
409 int ret = 0; 461 int ret = 0;
410 462
411 if (dac33->fifo_mode == ucontrol->value.integer.value[0]) 463 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
@@ -485,6 +537,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
485 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), 537 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
486 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power", 538 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
487 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), 539 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
540
541 SND_SOC_DAPM_PRE("Prepare Playback", playback_event),
488}; 542};
489 543
490static const struct snd_soc_dapm_route audio_map[] = { 544static const struct snd_soc_dapm_route audio_map[] = {
@@ -527,18 +581,21 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
527 break; 581 break;
528 case SND_SOC_BIAS_STANDBY: 582 case SND_SOC_BIAS_STANDBY:
529 if (codec->bias_level == SND_SOC_BIAS_OFF) { 583 if (codec->bias_level == SND_SOC_BIAS_OFF) {
584 /* Coming from OFF, switch on the codec */
530 ret = dac33_hard_power(codec, 1); 585 ret = dac33_hard_power(codec, 1);
531 if (ret != 0) 586 if (ret != 0)
532 return ret; 587 return ret;
533 }
534 588
535 dac33_soft_power(codec, 0); 589 dac33_init_chip(codec);
590 }
536 break; 591 break;
537 case SND_SOC_BIAS_OFF: 592 case SND_SOC_BIAS_OFF:
593 /* Do not power off, when the codec is already off */
594 if (codec->bias_level == SND_SOC_BIAS_OFF)
595 return 0;
538 ret = dac33_hard_power(codec, 0); 596 ret = dac33_hard_power(codec, 0);
539 if (ret != 0) 597 if (ret != 0)
540 return ret; 598 return ret;
541
542 break; 599 break;
543 } 600 }
544 codec->bias_level = level; 601 codec->bias_level = level;
@@ -555,13 +612,34 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
555 switch (dac33->fifo_mode) { 612 switch (dac33->fifo_mode) {
556 case DAC33_FIFO_MODE1: 613 case DAC33_FIFO_MODE1:
557 dac33_write16(codec, DAC33_NSAMPLE_MSB, 614 dac33_write16(codec, DAC33_NSAMPLE_MSB,
558 DAC33_THRREG(dac33->nsample)); 615 DAC33_THRREG(dac33->nsample + dac33->alarm_threshold));
616
617 /* Take the timestamps */
618 spin_lock_irq(&dac33->lock);
619 dac33->t_stamp2 = ktime_to_us(ktime_get());
620 dac33->t_stamp1 = dac33->t_stamp2;
621 spin_unlock_irq(&dac33->lock);
622
559 dac33_write16(codec, DAC33_PREFILL_MSB, 623 dac33_write16(codec, DAC33_PREFILL_MSB,
560 DAC33_THRREG(dac33->alarm_threshold)); 624 DAC33_THRREG(dac33->alarm_threshold));
625 /* Enable Alarm Threshold IRQ with a delay */
626 udelay(SAMPLES_TO_US(dac33->burst_rate,
627 dac33->alarm_threshold));
628 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
561 break; 629 break;
562 case DAC33_FIFO_MODE7: 630 case DAC33_FIFO_MODE7:
631 /* Take the timestamp */
632 spin_lock_irq(&dac33->lock);
633 dac33->t_stamp1 = ktime_to_us(ktime_get());
634 /* Move back the timestamp with drain time */
635 dac33->t_stamp1 -= dac33->mode7_us_to_lthr;
636 spin_unlock_irq(&dac33->lock);
637
563 dac33_write16(codec, DAC33_PREFILL_MSB, 638 dac33_write16(codec, DAC33_PREFILL_MSB,
564 DAC33_THRREG(10)); 639 DAC33_THRREG(MODE7_LTHR));
640
641 /* Enable Upper Threshold IRQ */
642 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
565 break; 643 break;
566 default: 644 default:
567 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n", 645 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
@@ -578,6 +656,11 @@ static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
578 656
579 switch (dac33->fifo_mode) { 657 switch (dac33->fifo_mode) {
580 case DAC33_FIFO_MODE1: 658 case DAC33_FIFO_MODE1:
659 /* Take the timestamp */
660 spin_lock_irq(&dac33->lock);
661 dac33->t_stamp2 = ktime_to_us(ktime_get());
662 spin_unlock_irq(&dac33->lock);
663
581 dac33_write16(codec, DAC33_NSAMPLE_MSB, 664 dac33_write16(codec, DAC33_NSAMPLE_MSB,
582 DAC33_THRREG(dac33->nsample)); 665 DAC33_THRREG(dac33->nsample));
583 break; 666 break;
@@ -628,31 +711,17 @@ static void dac33_work(struct work_struct *work)
628static irqreturn_t dac33_interrupt_handler(int irq, void *dev) 711static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
629{ 712{
630 struct snd_soc_codec *codec = dev; 713 struct snd_soc_codec *codec = dev;
631 struct tlv320dac33_priv *dac33 = codec->private_data; 714 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
632
633 queue_work(dac33->dac33_wq, &dac33->work);
634 715
635 return IRQ_HANDLED; 716 spin_lock(&dac33->lock);
636} 717 dac33->t_stamp1 = ktime_to_us(ktime_get());
718 spin_unlock(&dac33->lock);
637 719
638static void dac33_shutdown(struct snd_pcm_substream *substream, 720 /* Do not schedule the workqueue in Mode7 */
639 struct snd_soc_dai *dai) 721 if (dac33->fifo_mode != DAC33_FIFO_MODE7)
640{ 722 queue_work(dac33->dac33_wq, &dac33->work);
641 struct snd_soc_pcm_runtime *rtd = substream->private_data;
642 struct snd_soc_device *socdev = rtd->socdev;
643 struct snd_soc_codec *codec = socdev->card->codec;
644 struct tlv320dac33_priv *dac33 = codec->private_data;
645 unsigned int pwr_ctrl;
646 723
647 /* Stop pending workqueue */ 724 return IRQ_HANDLED;
648 if (dac33->fifo_mode)
649 cancel_work_sync(&dac33->work);
650
651 mutex_lock(&dac33->mutex);
652 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
653 pwr_ctrl &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
654 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
655 mutex_unlock(&dac33->mutex);
656} 725}
657 726
658static void dac33_oscwait(struct snd_soc_codec *codec) 727static void dac33_oscwait(struct snd_soc_codec *codec)
@@ -669,6 +738,31 @@ static void dac33_oscwait(struct snd_soc_codec *codec)
669 "internal oscillator calibration failed\n"); 738 "internal oscillator calibration failed\n");
670} 739}
671 740
741static int dac33_startup(struct snd_pcm_substream *substream,
742 struct snd_soc_dai *dai)
743{
744 struct snd_soc_pcm_runtime *rtd = substream->private_data;
745 struct snd_soc_device *socdev = rtd->socdev;
746 struct snd_soc_codec *codec = socdev->card->codec;
747 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
748
749 /* Stream started, save the substream pointer */
750 dac33->substream = substream;
751
752 return 0;
753}
754
755static void dac33_shutdown(struct snd_pcm_substream *substream,
756 struct snd_soc_dai *dai)
757{
758 struct snd_soc_pcm_runtime *rtd = substream->private_data;
759 struct snd_soc_device *socdev = rtd->socdev;
760 struct snd_soc_codec *codec = socdev->card->codec;
761 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
762
763 dac33->substream = NULL;
764}
765
672static int dac33_hw_params(struct snd_pcm_substream *substream, 766static int dac33_hw_params(struct snd_pcm_substream *substream,
673 struct snd_pcm_hw_params *params, 767 struct snd_pcm_hw_params *params,
674 struct snd_soc_dai *dai) 768 struct snd_soc_dai *dai)
@@ -715,7 +809,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
715 struct snd_soc_pcm_runtime *rtd = substream->private_data; 809 struct snd_soc_pcm_runtime *rtd = substream->private_data;
716 struct snd_soc_device *socdev = rtd->socdev; 810 struct snd_soc_device *socdev = rtd->socdev;
717 struct snd_soc_codec *codec = socdev->card->codec; 811 struct snd_soc_codec *codec = socdev->card->codec;
718 struct tlv320dac33_priv *dac33 = codec->private_data; 812 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
719 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 813 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
720 u8 aictrl_a, aictrl_b, fifoctrl_a; 814 u8 aictrl_a, aictrl_b, fifoctrl_a;
721 815
@@ -752,6 +846,17 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
752 } 846 }
753 847
754 mutex_lock(&dac33->mutex); 848 mutex_lock(&dac33->mutex);
849
850 if (!dac33->chip_power) {
851 /*
852 * Chip is not powered yet.
853 * Do the init in the dac33_set_bias_level later.
854 */
855 mutex_unlock(&dac33->mutex);
856 return 0;
857 }
858
859 dac33_soft_power(codec, 0);
755 dac33_soft_power(codec, 1); 860 dac33_soft_power(codec, 1);
756 861
757 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL); 862 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
@@ -799,11 +904,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
799 case DAC33_FIFO_MODE1: 904 case DAC33_FIFO_MODE1:
800 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B, 905 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
801 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL)); 906 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
802 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
803 break; 907 break;
804 case DAC33_FIFO_MODE7: 908 case DAC33_FIFO_MODE7:
805 /* Disable all interrupts */ 909 dac33_write(codec, DAC33_FIFO_IRQ_MODE_A,
806 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0); 910 DAC33_UTM(DAC33_FIFO_IRQ_MODE_LEVEL));
807 break; 911 break;
808 default: 912 default:
809 /* in FIFO bypass mode, the interrupts are not used */ 913 /* in FIFO bypass mode, the interrupts are not used */
@@ -822,7 +926,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
822 */ 926 */
823 fifoctrl_a &= ~DAC33_FBYPAS; 927 fifoctrl_a &= ~DAC33_FBYPAS;
824 fifoctrl_a &= ~DAC33_FAUTO; 928 fifoctrl_a &= ~DAC33_FAUTO;
825 aictrl_b &= ~DAC33_BCLKON; 929 if (dac33->keep_bclk)
930 aictrl_b |= DAC33_BCLKON;
931 else
932 aictrl_b &= ~DAC33_BCLKON;
826 break; 933 break;
827 case DAC33_FIFO_MODE7: 934 case DAC33_FIFO_MODE7:
828 /* 935 /*
@@ -833,7 +940,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
833 */ 940 */
834 fifoctrl_a &= ~DAC33_FBYPAS; 941 fifoctrl_a &= ~DAC33_FBYPAS;
835 fifoctrl_a |= DAC33_FAUTO; 942 fifoctrl_a |= DAC33_FAUTO;
836 aictrl_b &= ~DAC33_BCLKON; 943 if (dac33->keep_bclk)
944 aictrl_b |= DAC33_BCLKON;
945 else
946 aictrl_b &= ~DAC33_BCLKON;
837 break; 947 break;
838 default: 948 default:
839 /* 949 /*
@@ -875,10 +985,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
875 * Configure the threshold levels, and leave 10 sample space 985 * Configure the threshold levels, and leave 10 sample space
876 * at the bottom, and also at the top of the FIFO 986 * at the bottom, and also at the top of the FIFO
877 */ 987 */
878 dac33_write16(codec, DAC33_UTHR_MSB, 988 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(MODE7_UTHR));
879 DAC33_THRREG(DAC33_BUFFER_SIZE_SAMPLES - 10)); 989 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR));
880 dac33_write16(codec, DAC33_LTHR_MSB,
881 DAC33_THRREG(10));
882 break; 990 break;
883 default: 991 default:
884 break; 992 break;
@@ -894,9 +1002,13 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
894 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1002 struct snd_soc_pcm_runtime *rtd = substream->private_data;
895 struct snd_soc_device *socdev = rtd->socdev; 1003 struct snd_soc_device *socdev = rtd->socdev;
896 struct snd_soc_codec *codec = socdev->card->codec; 1004 struct snd_soc_codec *codec = socdev->card->codec;
897 struct tlv320dac33_priv *dac33 = codec->private_data; 1005 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
898 unsigned int nsample_limit; 1006 unsigned int nsample_limit;
899 1007
1008 /* In bypass mode we don't need to calculate */
1009 if (!dac33->fifo_mode)
1010 return;
1011
900 /* Number of samples (16bit, stereo) in one period */ 1012 /* Number of samples (16bit, stereo) in one period */
901 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4; 1013 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
902 1014
@@ -930,15 +1042,24 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
930 1042
931 if (dac33->nsample > dac33->nsample_max) 1043 if (dac33->nsample > dac33->nsample_max)
932 dac33->nsample = dac33->nsample_max; 1044 dac33->nsample = dac33->nsample_max;
933}
934 1045
935static int dac33_pcm_prepare(struct snd_pcm_substream *substream, 1046 switch (dac33->fifo_mode) {
936 struct snd_soc_dai *dai) 1047 case DAC33_FIFO_MODE1:
937{ 1048 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
938 dac33_calculate_times(substream); 1049 dac33->nsample);
939 dac33_prepare_chip(substream); 1050 dac33->t_stamp1 = 0;
1051 dac33->t_stamp2 = 0;
1052 break;
1053 case DAC33_FIFO_MODE7:
1054 dac33->mode7_us_to_lthr =
1055 SAMPLES_TO_US(substream->runtime->rate,
1056 MODE7_UTHR - MODE7_LTHR + 1);
1057 dac33->t_stamp1 = 0;
1058 break;
1059 default:
1060 break;
1061 }
940 1062
941 return 0;
942} 1063}
943 1064
944static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 1065static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -947,7 +1068,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
947 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1068 struct snd_soc_pcm_runtime *rtd = substream->private_data;
948 struct snd_soc_device *socdev = rtd->socdev; 1069 struct snd_soc_device *socdev = rtd->socdev;
949 struct snd_soc_codec *codec = socdev->card->codec; 1070 struct snd_soc_codec *codec = socdev->card->codec;
950 struct tlv320dac33_priv *dac33 = codec->private_data; 1071 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
951 int ret = 0; 1072 int ret = 0;
952 1073
953 switch (cmd) { 1074 switch (cmd) {
@@ -974,11 +1095,156 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
974 return ret; 1095 return ret;
975} 1096}
976 1097
1098static snd_pcm_sframes_t dac33_dai_delay(
1099 struct snd_pcm_substream *substream,
1100 struct snd_soc_dai *dai)
1101{
1102 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1103 struct snd_soc_device *socdev = rtd->socdev;
1104 struct snd_soc_codec *codec = socdev->card->codec;
1105 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1106 unsigned long long t0, t1, t_now;
1107 unsigned int time_delta;
1108 int samples_out, samples_in, samples;
1109 snd_pcm_sframes_t delay = 0;
1110
1111 switch (dac33->fifo_mode) {
1112 case DAC33_FIFO_BYPASS:
1113 break;
1114 case DAC33_FIFO_MODE1:
1115 spin_lock(&dac33->lock);
1116 t0 = dac33->t_stamp1;
1117 t1 = dac33->t_stamp2;
1118 spin_unlock(&dac33->lock);
1119 t_now = ktime_to_us(ktime_get());
1120
1121 /* We have not started to fill the FIFO yet, delay is 0 */
1122 if (!t1)
1123 goto out;
1124
1125 if (t0 > t1) {
1126 /*
1127 * Phase 1:
1128 * After Alarm threshold, and before nSample write
1129 */
1130 time_delta = t_now - t0;
1131 samples_out = time_delta ? US_TO_SAMPLES(
1132 substream->runtime->rate,
1133 time_delta) : 0;
1134
1135 if (likely(dac33->alarm_threshold > samples_out))
1136 delay = dac33->alarm_threshold - samples_out;
1137 else
1138 delay = 0;
1139 } else if ((t_now - t1) <= dac33->mode1_us_burst) {
1140 /*
1141 * Phase 2:
1142 * After nSample write (during burst operation)
1143 */
1144 time_delta = t_now - t0;
1145 samples_out = time_delta ? US_TO_SAMPLES(
1146 substream->runtime->rate,
1147 time_delta) : 0;
1148
1149 time_delta = t_now - t1;
1150 samples_in = time_delta ? US_TO_SAMPLES(
1151 dac33->burst_rate,
1152 time_delta) : 0;
1153
1154 samples = dac33->alarm_threshold;
1155 samples += (samples_in - samples_out);
1156
1157 if (likely(samples > 0))
1158 delay = samples;
1159 else
1160 delay = 0;
1161 } else {
1162 /*
1163 * Phase 3:
1164 * After burst operation, before next alarm threshold
1165 */
1166 time_delta = t_now - t0;
1167 samples_out = time_delta ? US_TO_SAMPLES(
1168 substream->runtime->rate,
1169 time_delta) : 0;
1170
1171 samples_in = dac33->nsample;
1172 samples = dac33->alarm_threshold;
1173 samples += (samples_in - samples_out);
1174
1175 if (likely(samples > 0))
1176 delay = samples > DAC33_BUFFER_SIZE_SAMPLES ?
1177 DAC33_BUFFER_SIZE_SAMPLES : samples;
1178 else
1179 delay = 0;
1180 }
1181 break;
1182 case DAC33_FIFO_MODE7:
1183 spin_lock(&dac33->lock);
1184 t0 = dac33->t_stamp1;
1185 spin_unlock(&dac33->lock);
1186 t_now = ktime_to_us(ktime_get());
1187
1188 /* We have not started to fill the FIFO yet, delay is 0 */
1189 if (!t0)
1190 goto out;
1191
1192 if (t_now <= t0) {
1193 /*
1194 * Either the timestamps are messed or equal. Report
1195 * maximum delay
1196 */
1197 delay = MODE7_UTHR;
1198 goto out;
1199 }
1200
1201 time_delta = t_now - t0;
1202 if (time_delta <= dac33->mode7_us_to_lthr) {
1203 /*
1204 * Phase 1:
1205 * After burst (draining phase)
1206 */
1207 samples_out = US_TO_SAMPLES(
1208 substream->runtime->rate,
1209 time_delta);
1210
1211 if (likely(MODE7_UTHR > samples_out))
1212 delay = MODE7_UTHR - samples_out;
1213 else
1214 delay = 0;
1215 } else {
1216 /*
1217 * Phase 2:
1218 * During burst operation
1219 */
1220 time_delta = time_delta - dac33->mode7_us_to_lthr;
1221
1222 samples_out = US_TO_SAMPLES(
1223 substream->runtime->rate,
1224 time_delta);
1225 samples_in = US_TO_SAMPLES(
1226 dac33->burst_rate,
1227 time_delta);
1228 delay = MODE7_LTHR + samples_in - samples_out;
1229
1230 if (unlikely(delay > MODE7_UTHR))
1231 delay = MODE7_UTHR;
1232 }
1233 break;
1234 default:
1235 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
1236 dac33->fifo_mode);
1237 break;
1238 }
1239out:
1240 return delay;
1241}
1242
977static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai, 1243static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
978 int clk_id, unsigned int freq, int dir) 1244 int clk_id, unsigned int freq, int dir)
979{ 1245{
980 struct snd_soc_codec *codec = codec_dai->codec; 1246 struct snd_soc_codec *codec = codec_dai->codec;
981 struct tlv320dac33_priv *dac33 = codec->private_data; 1247 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
982 u8 ioc_reg, asrcb_reg; 1248 u8 ioc_reg, asrcb_reg;
983 1249
984 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL); 1250 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
@@ -1008,7 +1274,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1008 unsigned int fmt) 1274 unsigned int fmt)
1009{ 1275{
1010 struct snd_soc_codec *codec = codec_dai->codec; 1276 struct snd_soc_codec *codec = codec_dai->codec;
1011 struct tlv320dac33_priv *dac33 = codec->private_data; 1277 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1012 u8 aictrl_a, aictrl_b; 1278 u8 aictrl_a, aictrl_b;
1013 1279
1014 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A); 1280 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
@@ -1059,35 +1325,6 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
1059 return 0; 1325 return 0;
1060} 1326}
1061 1327
1062static void dac33_init_chip(struct snd_soc_codec *codec)
1063{
1064 /* 44-46: DAC Control Registers */
1065 /* A : DAC sample rate Fsref/1.5 */
1066 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
1067 /* B : DAC src=normal, not muted */
1068 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
1069 DAC33_DACSRCL_LEFT);
1070 /* C : (defaults) */
1071 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
1072
1073 /* 64-65 : L&R DAC power control
1074 Line In -> OUT 1V/V Gain, DAC -> OUT 4V/V Gain*/
1075 dac33_write(codec, DAC33_LDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1076 dac33_write(codec, DAC33_RDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
1077
1078 /* 73 : volume soft stepping control,
1079 clock source = internal osc (?) */
1080 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
1081
1082 /* 66 : LOP/LOM Modes */
1083 dac33_write(codec, DAC33_OUT_AMP_CM_CTRL, 0xff);
1084
1085 /* 68 : LOM inverted from LOP */
1086 dac33_write(codec, DAC33_OUT_AMP_CTRL, (3<<2));
1087
1088 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
1089}
1090
1091static int dac33_soc_probe(struct platform_device *pdev) 1328static int dac33_soc_probe(struct platform_device *pdev)
1092{ 1329{
1093 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1330 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1099,12 +1336,7 @@ static int dac33_soc_probe(struct platform_device *pdev)
1099 1336
1100 codec = tlv320dac33_codec; 1337 codec = tlv320dac33_codec;
1101 socdev->card->codec = codec; 1338 socdev->card->codec = codec;
1102 dac33 = codec->private_data; 1339 dac33 = snd_soc_codec_get_drvdata(codec);
1103
1104 /* Power up the codec */
1105 dac33_hard_power(codec, 1);
1106 /* Set default configuration */
1107 dac33_init_chip(codec);
1108 1340
1109 /* register pcms */ 1341 /* register pcms */
1110 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1342 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -1122,12 +1354,6 @@ static int dac33_soc_probe(struct platform_device *pdev)
1122 1354
1123 dac33_add_widgets(codec); 1355 dac33_add_widgets(codec);
1124 1356
1125 /* power on device */
1126 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1127
1128 /* Bias level configuration has enabled regulator an extra time */
1129 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1130
1131 return 0; 1357 return 0;
1132 1358
1133pcm_err: 1359pcm_err:
@@ -1164,7 +1390,6 @@ static int dac33_soc_resume(struct platform_device *pdev)
1164 struct snd_soc_codec *codec = socdev->card->codec; 1390 struct snd_soc_codec *codec = socdev->card->codec;
1165 1391
1166 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1392 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1167 dac33_set_bias_level(codec, codec->suspend_bias_level);
1168 1393
1169 return 0; 1394 return 0;
1170} 1395}
@@ -1182,10 +1407,11 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1182#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE 1407#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1183 1408
1184static struct snd_soc_dai_ops dac33_dai_ops = { 1409static struct snd_soc_dai_ops dac33_dai_ops = {
1410 .startup = dac33_startup,
1185 .shutdown = dac33_shutdown, 1411 .shutdown = dac33_shutdown,
1186 .hw_params = dac33_hw_params, 1412 .hw_params = dac33_hw_params,
1187 .prepare = dac33_pcm_prepare,
1188 .trigger = dac33_pcm_trigger, 1413 .trigger = dac33_pcm_trigger,
1414 .delay = dac33_dai_delay,
1189 .set_sysclk = dac33_set_dai_sysclk, 1415 .set_sysclk = dac33_set_dai_sysclk,
1190 .set_fmt = dac33_set_dai_fmt, 1416 .set_fmt = dac33_set_dai_fmt,
1191}; 1417};
@@ -1221,11 +1447,12 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1221 return -ENOMEM; 1447 return -ENOMEM;
1222 1448
1223 codec = &dac33->codec; 1449 codec = &dac33->codec;
1224 codec->private_data = dac33; 1450 snd_soc_codec_set_drvdata(codec, dac33);
1225 codec->control_data = client; 1451 codec->control_data = client;
1226 1452
1227 mutex_init(&codec->mutex); 1453 mutex_init(&codec->mutex);
1228 mutex_init(&dac33->mutex); 1454 mutex_init(&dac33->mutex);
1455 spin_lock_init(&dac33->lock);
1229 INIT_LIST_HEAD(&codec->dapm_widgets); 1456 INIT_LIST_HEAD(&codec->dapm_widgets);
1230 INIT_LIST_HEAD(&codec->dapm_paths); 1457 INIT_LIST_HEAD(&codec->dapm_paths);
1231 1458
@@ -1236,6 +1463,7 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1236 codec->hw_write = (hw_write_t) i2c_master_send; 1463 codec->hw_write = (hw_write_t) i2c_master_send;
1237 codec->bias_level = SND_SOC_BIAS_OFF; 1464 codec->bias_level = SND_SOC_BIAS_OFF;
1238 codec->set_bias_level = dac33_set_bias_level; 1465 codec->set_bias_level = dac33_set_bias_level;
1466 codec->idle_bias_off = 1;
1239 codec->dai = &dac33_dai; 1467 codec->dai = &dac33_dai;
1240 codec->num_dai = 1; 1468 codec->num_dai = 1;
1241 codec->reg_cache_size = ARRAY_SIZE(dac33_reg); 1469 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
@@ -1250,8 +1478,12 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1250 1478
1251 dac33->power_gpio = pdata->power_gpio; 1479 dac33->power_gpio = pdata->power_gpio;
1252 dac33->burst_bclkdiv = pdata->burst_bclkdiv; 1480 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1481 /* Pre calculate the burst rate */
1482 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
1483 dac33->keep_bclk = pdata->keep_bclk;
1253 dac33->irq = client->irq; 1484 dac33->irq = client->irq;
1254 dac33->nsample = NSAMPLE_MAX; 1485 dac33->nsample = NSAMPLE_MAX;
1486 dac33->nsample_max = NSAMPLE_MAX;
1255 /* Disable FIFO use by default */ 1487 /* Disable FIFO use by default */
1256 dac33->fifo_mode = DAC33_FIFO_BYPASS; 1488 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1257 1489
@@ -1272,8 +1504,6 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1272 goto error_gpio; 1504 goto error_gpio;
1273 } 1505 }
1274 gpio_direction_output(dac33->power_gpio, 0); 1506 gpio_direction_output(dac33->power_gpio, 0);
1275 } else {
1276 dac33->chip_power = 1;
1277 } 1507 }
1278 1508
1279 /* Check if the IRQ number is valid and request it */ 1509 /* Check if the IRQ number is valid and request it */
@@ -1311,12 +1541,14 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1311 goto err_get; 1541 goto err_get;
1312 } 1542 }
1313 1543
1314 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies), 1544 /* Read the tlv320dac33 ID registers */
1315 dac33->supplies); 1545 ret = dac33_hard_power(codec, 1);
1316 if (ret != 0) { 1546 if (ret != 0) {
1317 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); 1547 dev_err(codec->dev, "Failed to power up codec: %d\n", ret);
1318 goto err_enable; 1548 goto error_codec;
1319 } 1549 }
1550 dac33_read_id(codec);
1551 dac33_hard_power(codec, 0);
1320 1552
1321 ret = snd_soc_register_codec(codec); 1553 ret = snd_soc_register_codec(codec);
1322 if (ret != 0) { 1554 if (ret != 0) {
@@ -1331,14 +1563,9 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1331 goto error_codec; 1563 goto error_codec;
1332 } 1564 }
1333 1565
1334 /* Shut down the codec for now */
1335 dac33_hard_power(codec, 0);
1336
1337 return ret; 1566 return ret;
1338 1567
1339error_codec: 1568error_codec:
1340 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1341err_enable:
1342 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); 1569 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1343err_get: 1570err_get:
1344 if (dac33->irq >= 0) { 1571 if (dac33->irq >= 0) {
@@ -1362,7 +1589,9 @@ static int __devexit dac33_i2c_remove(struct i2c_client *client)
1362 struct tlv320dac33_priv *dac33; 1589 struct tlv320dac33_priv *dac33;
1363 1590
1364 dac33 = i2c_get_clientdata(client); 1591 dac33 = i2c_get_clientdata(client);
1365 dac33_hard_power(&dac33->codec, 0); 1592
1593 if (unlikely(dac33->chip_power))
1594 dac33_hard_power(&dac33->codec, 0);
1366 1595
1367 if (dac33->power_gpio >= 0) 1596 if (dac33->power_gpio >= 0)
1368 gpio_free(dac33->power_gpio); 1597 gpio_free(dac33->power_gpio);
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 569ad8758a84..99b70e5978a2 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -36,24 +36,14 @@
36 36
37static struct i2c_client *tpa6130a2_client; 37static struct i2c_client *tpa6130a2_client;
38 38
39#define TPA6130A2_NUM_SUPPLIES 2
40static const char *tpa6130a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
41 "CPVSS",
42 "Vdd",
43};
44
45static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
46 "HPVdd",
47 "AVdd",
48};
49
50/* This struct is used to save the context */ 39/* This struct is used to save the context */
51struct tpa6130a2_data { 40struct tpa6130a2_data {
52 struct mutex mutex; 41 struct mutex mutex;
53 unsigned char regs[TPA6130A2_CACHEREGNUM]; 42 unsigned char regs[TPA6130A2_CACHEREGNUM];
54 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES]; 43 struct regulator *supply;
55 int power_gpio; 44 int power_gpio;
56 unsigned char power_state; 45 unsigned char power_state;
46 enum tpa_model id;
57}; 47};
58 48
59static int tpa6130a2_i2c_read(int reg) 49static int tpa6130a2_i2c_read(int reg)
@@ -135,11 +125,10 @@ static int tpa6130a2_power(int power)
135 if (data->power_gpio >= 0) 125 if (data->power_gpio >= 0)
136 gpio_set_value(data->power_gpio, 1); 126 gpio_set_value(data->power_gpio, 1);
137 127
138 ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), 128 ret = regulator_enable(data->supply);
139 data->supplies);
140 if (ret != 0) { 129 if (ret != 0) {
141 dev_err(&tpa6130a2_client->dev, 130 dev_err(&tpa6130a2_client->dev,
142 "Failed to enable supplies: %d\n", ret); 131 "Failed to enable supply: %d\n", ret);
143 goto exit; 132 goto exit;
144 } 133 }
145 134
@@ -160,11 +149,10 @@ static int tpa6130a2_power(int power)
160 if (data->power_gpio >= 0) 149 if (data->power_gpio >= 0)
161 gpio_set_value(data->power_gpio, 0); 150 gpio_set_value(data->power_gpio, 0);
162 151
163 ret = regulator_bulk_disable(ARRAY_SIZE(data->supplies), 152 ret = regulator_disable(data->supply);
164 data->supplies);
165 if (ret != 0) { 153 if (ret != 0) {
166 dev_err(&tpa6130a2_client->dev, 154 dev_err(&tpa6130a2_client->dev,
167 "Failed to disable supplies: %d\n", ret); 155 "Failed to disable supply: %d\n", ret);
168 goto exit; 156 goto exit;
169 } 157 }
170 158
@@ -176,7 +164,7 @@ exit:
176 return ret; 164 return ret;
177} 165}
178 166
179static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol, 167static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol) 168 struct snd_ctl_elem_value *ucontrol)
181{ 169{
182 struct soc_mixer_control *mc = 170 struct soc_mixer_control *mc =
@@ -184,7 +172,8 @@ static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
184 struct tpa6130a2_data *data; 172 struct tpa6130a2_data *data;
185 unsigned int reg = mc->reg; 173 unsigned int reg = mc->reg;
186 unsigned int shift = mc->shift; 174 unsigned int shift = mc->shift;
187 unsigned int mask = mc->max; 175 int max = mc->max;
176 unsigned int mask = (1 << fls(max)) - 1;
188 unsigned int invert = mc->invert; 177 unsigned int invert = mc->invert;
189 178
190 BUG_ON(tpa6130a2_client == NULL); 179 BUG_ON(tpa6130a2_client == NULL);
@@ -197,13 +186,13 @@ static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
197 186
198 if (invert) 187 if (invert)
199 ucontrol->value.integer.value[0] = 188 ucontrol->value.integer.value[0] =
200 mask - ucontrol->value.integer.value[0]; 189 max - ucontrol->value.integer.value[0];
201 190
202 mutex_unlock(&data->mutex); 191 mutex_unlock(&data->mutex);
203 return 0; 192 return 0;
204} 193}
205 194
206static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol, 195static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol) 196 struct snd_ctl_elem_value *ucontrol)
208{ 197{
209 struct soc_mixer_control *mc = 198 struct soc_mixer_control *mc =
@@ -211,7 +200,8 @@ static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
211 struct tpa6130a2_data *data; 200 struct tpa6130a2_data *data;
212 unsigned int reg = mc->reg; 201 unsigned int reg = mc->reg;
213 unsigned int shift = mc->shift; 202 unsigned int shift = mc->shift;
214 unsigned int mask = mc->max; 203 int max = mc->max;
204 unsigned int mask = (1 << fls(max)) - 1;
215 unsigned int invert = mc->invert; 205 unsigned int invert = mc->invert;
216 unsigned int val = (ucontrol->value.integer.value[0] & mask); 206 unsigned int val = (ucontrol->value.integer.value[0] & mask);
217 unsigned int val_reg; 207 unsigned int val_reg;
@@ -220,7 +210,7 @@ static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
220 data = i2c_get_clientdata(tpa6130a2_client); 210 data = i2c_get_clientdata(tpa6130a2_client);
221 211
222 if (invert) 212 if (invert)
223 val = mask - val; 213 val = max - val;
224 214
225 mutex_lock(&data->mutex); 215 mutex_lock(&data->mutex);
226 216
@@ -260,10 +250,24 @@ static const unsigned int tpa6130_tlv[] = {
260static const struct snd_kcontrol_new tpa6130a2_controls[] = { 250static const struct snd_kcontrol_new tpa6130a2_controls[] = {
261 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume", 251 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
262 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0, 252 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
263 tpa6130a2_get_reg, tpa6130a2_set_reg, 253 tpa6130a2_get_volsw, tpa6130a2_put_volsw,
264 tpa6130_tlv), 254 tpa6130_tlv),
265}; 255};
266 256
257static const unsigned int tpa6140_tlv[] = {
258 TLV_DB_RANGE_HEAD(3),
259 0, 8, TLV_DB_SCALE_ITEM(-5900, 400, 0),
260 9, 16, TLV_DB_SCALE_ITEM(-2500, 200, 0),
261 17, 31, TLV_DB_SCALE_ITEM(-1000, 100, 0),
262};
263
264static const struct snd_kcontrol_new tpa6140a2_controls[] = {
265 SOC_SINGLE_EXT_TLV("TPA6140A2 Headphone Playback Volume",
266 TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
267 tpa6130a2_get_volsw, tpa6130a2_put_volsw,
268 tpa6140_tlv),
269};
270
267/* 271/*
268 * Enable or disable channel (left or right) 272 * Enable or disable channel (left or right)
269 * The bit number for mute and amplifier are the same per channel: 273 * The bit number for mute and amplifier are the same per channel:
@@ -355,8 +359,8 @@ static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
355 0, 0, tpa6130a2_supply_event, 359 0, 0, tpa6130a2_supply_event,
356 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 360 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
357 /* Outputs */ 361 /* Outputs */
358 SND_SOC_DAPM_HP("TPA6130A2 Headphone Left", NULL), 362 SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Left"),
359 SND_SOC_DAPM_HP("TPA6130A2 Headphone Right", NULL), 363 SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Right"),
360}; 364};
361 365
362static const struct snd_soc_dapm_route audio_map[] = { 366static const struct snd_soc_dapm_route audio_map[] = {
@@ -369,13 +373,22 @@ static const struct snd_soc_dapm_route audio_map[] = {
369 373
370int tpa6130a2_add_controls(struct snd_soc_codec *codec) 374int tpa6130a2_add_controls(struct snd_soc_codec *codec)
371{ 375{
376 struct tpa6130a2_data *data;
377
378 BUG_ON(tpa6130a2_client == NULL);
379 data = i2c_get_clientdata(tpa6130a2_client);
380
372 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets, 381 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
373 ARRAY_SIZE(tpa6130a2_dapm_widgets)); 382 ARRAY_SIZE(tpa6130a2_dapm_widgets));
374 383
375 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 384 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
376 385
377 return snd_soc_add_controls(codec, tpa6130a2_controls, 386 if (data->id == TPA6140A2)
378 ARRAY_SIZE(tpa6130a2_controls)); 387 return snd_soc_add_controls(codec, tpa6140a2_controls,
388 ARRAY_SIZE(tpa6140a2_controls));
389 else
390 return snd_soc_add_controls(codec, tpa6130a2_controls,
391 ARRAY_SIZE(tpa6130a2_controls));
379 392
380} 393}
381EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 394EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
@@ -386,7 +399,8 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
386 struct device *dev; 399 struct device *dev;
387 struct tpa6130a2_data *data; 400 struct tpa6130a2_data *data;
388 struct tpa6130a2_platform_data *pdata; 401 struct tpa6130a2_platform_data *pdata;
389 int i, ret; 402 const char *regulator;
403 int ret;
390 404
391 dev = &client->dev; 405 dev = &client->dev;
392 406
@@ -408,6 +422,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
408 422
409 pdata = client->dev.platform_data; 423 pdata = client->dev.platform_data;
410 data->power_gpio = pdata->power_gpio; 424 data->power_gpio = pdata->power_gpio;
425 data->id = pdata->id;
411 426
412 mutex_init(&data->mutex); 427 mutex_init(&data->mutex);
413 428
@@ -426,26 +441,22 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
426 gpio_direction_output(data->power_gpio, 0); 441 gpio_direction_output(data->power_gpio, 0);
427 } 442 }
428 443
429 switch (pdata->id) { 444 switch (data->id) {
445 default:
446 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
447 pdata->id);
430 case TPA6130A2: 448 case TPA6130A2:
431 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 449 regulator = "Vdd";
432 data->supplies[i].supply = tpa6130a2_supply_names[i];
433 break; 450 break;
434 case TPA6140A2: 451 case TPA6140A2:
435 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) 452 regulator = "AVdd";
436 data->supplies[i].supply = tpa6140a2_supply_names[i];;
437 break; 453 break;
438 default:
439 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
440 pdata->id);
441 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
442 data->supplies[i].supply = tpa6130a2_supply_names[i];
443 } 454 }
444 455
445 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), 456 data->supply = regulator_get(dev, regulator);
446 data->supplies); 457 if (IS_ERR(data->supply)) {
447 if (ret != 0) { 458 ret = PTR_ERR(data->supply);
448 dev_err(dev, "Failed to request supplies: %d\n", ret); 459 dev_err(dev, "Failed to request supply: %d\n", ret);
449 goto err_regulator; 460 goto err_regulator;
450 } 461 }
451 462
@@ -468,7 +479,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client,
468 return 0; 479 return 0;
469 480
470err_power: 481err_power:
471 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies); 482 regulator_put(data->supply);
472err_regulator: 483err_regulator:
473 if (data->power_gpio >= 0) 484 if (data->power_gpio >= 0)
474 gpio_free(data->power_gpio); 485 gpio_free(data->power_gpio);
@@ -489,7 +500,7 @@ static int __devexit tpa6130a2_remove(struct i2c_client *client)
489 if (data->power_gpio >= 0) 500 if (data->power_gpio >= 0)
490 gpio_free(data->power_gpio); 501 gpio_free(data->power_gpio);
491 502
492 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies); 503 regulator_put(data->supply);
493 504
494 kfree(data); 505 kfree(data);
495 tpa6130a2_client = NULL; 506 tpa6130a2_client = NULL;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 520ffd6536c3..b4fcdb01fc49 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -124,6 +124,8 @@ struct twl4030_priv {
124 struct snd_soc_codec codec; 124 struct snd_soc_codec codec;
125 125
126 unsigned int codec_powered; 126 unsigned int codec_powered;
127
128 /* reference counts of AIF/APLL users */
127 unsigned int apll_enabled; 129 unsigned int apll_enabled;
128 130
129 struct snd_pcm_substream *master_substream; 131 struct snd_pcm_substream *master_substream;
@@ -136,9 +138,11 @@ struct twl4030_priv {
136 138
137 unsigned int sysclk; 139 unsigned int sysclk;
138 140
139 /* Headset output state handling */ 141 /* Output (with associated amp) states */
140 unsigned int hsl_enabled; 142 u8 hsl_enabled, hsr_enabled;
141 unsigned int hsr_enabled; 143 u8 earpiece_enabled;
144 u8 predrivel_enabled, predriver_enabled;
145 u8 carkitl_enabled, carkitr_enabled;
142}; 146};
143 147
144/* 148/*
@@ -174,17 +178,52 @@ static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
174static int twl4030_write(struct snd_soc_codec *codec, 178static int twl4030_write(struct snd_soc_codec *codec,
175 unsigned int reg, unsigned int value) 179 unsigned int reg, unsigned int value)
176{ 180{
181 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
182 int write_to_reg = 0;
183
177 twl4030_write_reg_cache(codec, reg, value); 184 twl4030_write_reg_cache(codec, reg, value);
178 if (likely(reg < TWL4030_REG_SW_SHADOW)) 185 if (likely(reg < TWL4030_REG_SW_SHADOW)) {
179 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, 186 /* Decide if the given register can be written */
180 reg); 187 switch (reg) {
181 else 188 case TWL4030_REG_EAR_CTL:
182 return 0; 189 if (twl4030->earpiece_enabled)
190 write_to_reg = 1;
191 break;
192 case TWL4030_REG_PREDL_CTL:
193 if (twl4030->predrivel_enabled)
194 write_to_reg = 1;
195 break;
196 case TWL4030_REG_PREDR_CTL:
197 if (twl4030->predriver_enabled)
198 write_to_reg = 1;
199 break;
200 case TWL4030_REG_PRECKL_CTL:
201 if (twl4030->carkitl_enabled)
202 write_to_reg = 1;
203 break;
204 case TWL4030_REG_PRECKR_CTL:
205 if (twl4030->carkitr_enabled)
206 write_to_reg = 1;
207 break;
208 case TWL4030_REG_HS_GAIN_SET:
209 if (twl4030->hsl_enabled || twl4030->hsr_enabled)
210 write_to_reg = 1;
211 break;
212 default:
213 /* All other register can be written */
214 write_to_reg = 1;
215 break;
216 }
217 if (write_to_reg)
218 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
219 value, reg);
220 }
221 return 0;
183} 222}
184 223
185static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 224static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
186{ 225{
187 struct twl4030_priv *twl4030 = codec->private_data; 226 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
188 int mode; 227 int mode;
189 228
190 if (enable == twl4030->codec_powered) 229 if (enable == twl4030->codec_powered)
@@ -222,28 +261,28 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
222 261
223static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) 262static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
224{ 263{
225 struct twl4030_priv *twl4030 = codec->private_data; 264 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
226 int status; 265 int status = -1;
227 266
228 if (enable == twl4030->apll_enabled) 267 if (enable) {
229 return; 268 twl4030->apll_enabled++;
230 269 if (twl4030->apll_enabled == 1)
231 if (enable) 270 status = twl4030_codec_enable_resource(
232 /* Enable PLL */ 271 TWL4030_CODEC_RES_APLL);
233 status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL); 272 } else {
234 else 273 twl4030->apll_enabled--;
235 /* Disable PLL */ 274 if (!twl4030->apll_enabled)
236 status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); 275 status = twl4030_codec_disable_resource(
276 TWL4030_CODEC_RES_APLL);
277 }
237 278
238 if (status >= 0) 279 if (status >= 0)
239 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); 280 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
240
241 twl4030->apll_enabled = enable;
242} 281}
243 282
244static void twl4030_power_up(struct snd_soc_codec *codec) 283static void twl4030_power_up(struct snd_soc_codec *codec)
245{ 284{
246 struct twl4030_priv *twl4030 = codec->private_data; 285 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
247 u8 anamicl, regmisc1, byte; 286 u8 anamicl, regmisc1, byte;
248 int i = 0; 287 int i = 0;
249 288
@@ -526,26 +565,26 @@ static int micpath_event(struct snd_soc_dapm_widget *w,
526 * Output PGA builder: 565 * Output PGA builder:
527 * Handle the muting and unmuting of the given output (turning off the 566 * Handle the muting and unmuting of the given output (turning off the
528 * amplifier associated with the output pin) 567 * amplifier associated with the output pin)
529 * On mute bypass the reg_cache and mute the volume 568 * On mute bypass the reg_cache and write 0 to the register
530 * On unmute: restore the register content 569 * On unmute: restore the register content from the reg_cache
531 * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R 570 * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R
532 */ 571 */
533#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \ 572#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
534static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ 573static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
535 struct snd_kcontrol *kcontrol, int event) \ 574 struct snd_kcontrol *kcontrol, int event) \
536{ \ 575{ \
537 u8 reg_val; \ 576 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \
538 \ 577 \
539 switch (event) { \ 578 switch (event) { \
540 case SND_SOC_DAPM_POST_PMU: \ 579 case SND_SOC_DAPM_POST_PMU: \
580 twl4030->pin_name##_enabled = 1; \
541 twl4030_write(w->codec, reg, \ 581 twl4030_write(w->codec, reg, \
542 twl4030_read_reg_cache(w->codec, reg)); \ 582 twl4030_read_reg_cache(w->codec, reg)); \
543 break; \ 583 break; \
544 case SND_SOC_DAPM_POST_PMD: \ 584 case SND_SOC_DAPM_POST_PMD: \
545 reg_val = twl4030_read_reg_cache(w->codec, reg); \ 585 twl4030->pin_name##_enabled = 0; \
546 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ 586 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
547 reg_val & (~mask), \ 587 0, reg); \
548 reg); \
549 break; \ 588 break; \
550 } \ 589 } \
551 return 0; \ 590 return 0; \
@@ -636,13 +675,38 @@ static int apll_event(struct snd_soc_dapm_widget *w,
636 return 0; 675 return 0;
637} 676}
638 677
678static int aif_event(struct snd_soc_dapm_widget *w,
679 struct snd_kcontrol *kcontrol, int event)
680{
681 u8 audio_if;
682
683 audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF);
684 switch (event) {
685 case SND_SOC_DAPM_PRE_PMU:
686 /* Enable AIF */
687 /* enable the PLL before we use it to clock the DAI */
688 twl4030_apll_enable(w->codec, 1);
689
690 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
691 audio_if | TWL4030_AIF_EN);
692 break;
693 case SND_SOC_DAPM_POST_PMD:
694 /* disable the DAI before we stop it's source PLL */
695 twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
696 audio_if & ~TWL4030_AIF_EN);
697 twl4030_apll_enable(w->codec, 0);
698 break;
699 }
700 return 0;
701}
702
639static void headset_ramp(struct snd_soc_codec *codec, int ramp) 703static void headset_ramp(struct snd_soc_codec *codec, int ramp)
640{ 704{
641 struct snd_soc_device *socdev = codec->socdev; 705 struct snd_soc_device *socdev = codec->socdev;
642 struct twl4030_setup_data *setup = socdev->codec_data; 706 struct twl4030_setup_data *setup = socdev->codec_data;
643 707
644 unsigned char hs_gain, hs_pop; 708 unsigned char hs_gain, hs_pop;
645 struct twl4030_priv *twl4030 = codec->private_data; 709 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
646 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 710 /* Base values for ramp delay calculation: 2^19 - 2^26 */
647 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 711 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
648 8388608, 16777216, 33554432, 67108864}; 712 8388608, 16777216, 33554432, 67108864};
@@ -665,7 +729,10 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
665 /* Headset ramp-up according to the TRM */ 729 /* Headset ramp-up according to the TRM */
666 hs_pop |= TWL4030_VMID_EN; 730 hs_pop |= TWL4030_VMID_EN;
667 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 731 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
668 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain); 732 /* Actually write to the register */
733 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
734 hs_gain,
735 TWL4030_REG_HS_GAIN_SET);
669 hs_pop |= TWL4030_RAMP_EN; 736 hs_pop |= TWL4030_RAMP_EN;
670 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 737 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
671 /* Wait ramp delay time + 1, so the VMID can settle */ 738 /* Wait ramp delay time + 1, so the VMID can settle */
@@ -702,7 +769,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
702static int headsetlpga_event(struct snd_soc_dapm_widget *w, 769static int headsetlpga_event(struct snd_soc_dapm_widget *w,
703 struct snd_kcontrol *kcontrol, int event) 770 struct snd_kcontrol *kcontrol, int event)
704{ 771{
705 struct twl4030_priv *twl4030 = w->codec->private_data; 772 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
706 773
707 switch (event) { 774 switch (event) {
708 case SND_SOC_DAPM_POST_PMU: 775 case SND_SOC_DAPM_POST_PMU:
@@ -726,7 +793,7 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w,
726static int headsetrpga_event(struct snd_soc_dapm_widget *w, 793static int headsetrpga_event(struct snd_soc_dapm_widget *w,
727 struct snd_kcontrol *kcontrol, int event) 794 struct snd_kcontrol *kcontrol, int event)
728{ 795{
729 struct twl4030_priv *twl4030 = w->codec->private_data; 796 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
730 797
731 switch (event) { 798 switch (event) {
732 case SND_SOC_DAPM_POST_PMU: 799 case SND_SOC_DAPM_POST_PMU:
@@ -918,7 +985,7 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
918 struct snd_ctl_elem_value *ucontrol) 985 struct snd_ctl_elem_value *ucontrol)
919{ 986{
920 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 987 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
921 struct twl4030_priv *twl4030 = codec->private_data; 988 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
922 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 989 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
923 unsigned short val; 990 unsigned short val;
924 unsigned short mask, bitmask; 991 unsigned short mask, bitmask;
@@ -1036,6 +1103,16 @@ static const struct soc_enum twl4030_vibradir_enum =
1036 ARRAY_SIZE(twl4030_vibradir_texts), 1103 ARRAY_SIZE(twl4030_vibradir_texts),
1037 twl4030_vibradir_texts); 1104 twl4030_vibradir_texts);
1038 1105
1106/* Digimic Left and right swapping */
1107static const char *twl4030_digimicswap_texts[] = {
1108 "Not swapped", "Swapped",
1109};
1110
1111static const struct soc_enum twl4030_digimicswap_enum =
1112 SOC_ENUM_SINGLE(TWL4030_REG_MISC_SET_1, 0,
1113 ARRAY_SIZE(twl4030_digimicswap_texts),
1114 twl4030_digimicswap_texts);
1115
1039static const struct snd_kcontrol_new twl4030_snd_controls[] = { 1116static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1040 /* Codec operation mode control */ 1117 /* Codec operation mode control */
1041 SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum, 1118 SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum,
@@ -1112,6 +1189,8 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1112 1189
1113 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), 1190 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
1114 SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum), 1191 SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum),
1192
1193 SOC_ENUM("Digimic LR Swap", twl4030_digimicswap_enum),
1115}; 1194};
1116 1195
1117static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { 1196static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
@@ -1128,8 +1207,6 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1128 SND_SOC_DAPM_INPUT("DIGIMIC1"), 1207 SND_SOC_DAPM_INPUT("DIGIMIC1"),
1129 1208
1130 /* Outputs */ 1209 /* Outputs */
1131 SND_SOC_DAPM_OUTPUT("OUTL"),
1132 SND_SOC_DAPM_OUTPUT("OUTR"),
1133 SND_SOC_DAPM_OUTPUT("EARPIECE"), 1210 SND_SOC_DAPM_OUTPUT("EARPIECE"),
1134 SND_SOC_DAPM_OUTPUT("PREDRIVEL"), 1211 SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
1135 SND_SOC_DAPM_OUTPUT("PREDRIVER"), 1212 SND_SOC_DAPM_OUTPUT("PREDRIVER"),
@@ -1141,6 +1218,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1141 SND_SOC_DAPM_OUTPUT("HFR"), 1218 SND_SOC_DAPM_OUTPUT("HFR"),
1142 SND_SOC_DAPM_OUTPUT("VIBRA"), 1219 SND_SOC_DAPM_OUTPUT("VIBRA"),
1143 1220
1221 /* AIF and APLL clocks for running DAIs (including loopback) */
1222 SND_SOC_DAPM_OUTPUT("Virtual HiFi OUT"),
1223 SND_SOC_DAPM_INPUT("Virtual HiFi IN"),
1224 SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
1225
1144 /* DACs */ 1226 /* DACs */
1145 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback", 1227 SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
1146 SND_SOC_NOPM, 0, 0), 1228 SND_SOC_NOPM, 0, 0),
@@ -1204,7 +1286,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1204 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event, 1286 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1205 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), 1287 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1206 1288
1207 SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0), 1289 SND_SOC_DAPM_SUPPLY("AIF Enable", SND_SOC_NOPM, 0, 0, aif_event,
1290 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1208 1291
1209 /* Output MIXER controls */ 1292 /* Output MIXER controls */
1210 /* Earpiece */ 1293 /* Earpiece */
@@ -1334,10 +1417,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1334 {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, 1417 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1335 1418
1336 /* Supply for the digital part (APLL) */ 1419 /* Supply for the digital part (APLL) */
1337 {"Digital R1 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital L1 Playback Mixer", NULL, "APLL Enable"},
1339 {"Digital R2 Playback Mixer", NULL, "APLL Enable"},
1340 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1341 {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, 1420 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1342 1421
1343 {"Digital R1 Playback Mixer", NULL, "AIF Enable"}, 1422 {"Digital R1 Playback Mixer", NULL, "AIF Enable"},
@@ -1411,8 +1490,14 @@ static const struct snd_soc_dapm_route intercon[] = {
1411 {"Vibra Mux", "AudioR2", "DAC Right2"}, 1490 {"Vibra Mux", "AudioR2", "DAC Right2"},
1412 1491
1413 /* outputs */ 1492 /* outputs */
1414 {"OUTL", NULL, "Analog L2 Playback Mixer"}, 1493 /* Must be always connected (for AIF and APLL) */
1415 {"OUTR", NULL, "Analog R2 Playback Mixer"}, 1494 {"Virtual HiFi OUT", NULL, "Digital L1 Playback Mixer"},
1495 {"Virtual HiFi OUT", NULL, "Digital R1 Playback Mixer"},
1496 {"Virtual HiFi OUT", NULL, "Digital L2 Playback Mixer"},
1497 {"Virtual HiFi OUT", NULL, "Digital R2 Playback Mixer"},
1498 /* Must be always connected (for APLL) */
1499 {"Virtual Voice OUT", NULL, "Digital Voice Playback Mixer"},
1500 /* Physical outputs */
1416 {"EARPIECE", NULL, "Earpiece PGA"}, 1501 {"EARPIECE", NULL, "Earpiece PGA"},
1417 {"PREDRIVEL", NULL, "PredriveL PGA"}, 1502 {"PREDRIVEL", NULL, "PredriveL PGA"},
1418 {"PREDRIVER", NULL, "PredriveR PGA"}, 1503 {"PREDRIVER", NULL, "PredriveR PGA"},
@@ -1426,6 +1511,12 @@ static const struct snd_soc_dapm_route intercon[] = {
1426 {"VIBRA", NULL, "Vibra Route"}, 1511 {"VIBRA", NULL, "Vibra Route"},
1427 1512
1428 /* Capture path */ 1513 /* Capture path */
1514 /* Must be always connected (for AIF and APLL) */
1515 {"ADC Virtual Left1", NULL, "Virtual HiFi IN"},
1516 {"ADC Virtual Right1", NULL, "Virtual HiFi IN"},
1517 {"ADC Virtual Left2", NULL, "Virtual HiFi IN"},
1518 {"ADC Virtual Right2", NULL, "Virtual HiFi IN"},
1519 /* Physical inputs */
1429 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"}, 1520 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
1430 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"}, 1521 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
1431 {"Analog Left", "AUXL Capture Switch", "AUXL"}, 1522 {"Analog Left", "AUXL Capture Switch", "AUXL"},
@@ -1458,11 +1549,6 @@ static const struct snd_soc_dapm_route intercon[] = {
1458 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1549 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1459 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1550 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1460 1551
1461 {"ADC Virtual Left1", NULL, "APLL Enable"},
1462 {"ADC Virtual Right1", NULL, "APLL Enable"},
1463 {"ADC Virtual Left2", NULL, "APLL Enable"},
1464 {"ADC Virtual Right2", NULL, "APLL Enable"},
1465
1466 {"ADC Virtual Left1", NULL, "AIF Enable"}, 1552 {"ADC Virtual Left1", NULL, "AIF Enable"},
1467 {"ADC Virtual Right1", NULL, "AIF Enable"}, 1553 {"ADC Virtual Right1", NULL, "AIF Enable"},
1468 {"ADC Virtual Left2", NULL, "AIF Enable"}, 1554 {"ADC Virtual Left2", NULL, "AIF Enable"},
@@ -1588,7 +1674,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1588 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1674 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1589 struct snd_soc_device *socdev = rtd->socdev; 1675 struct snd_soc_device *socdev = rtd->socdev;
1590 struct snd_soc_codec *codec = socdev->card->codec; 1676 struct snd_soc_codec *codec = socdev->card->codec;
1591 struct twl4030_priv *twl4030 = codec->private_data; 1677 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1592 1678
1593 if (twl4030->master_substream) { 1679 if (twl4030->master_substream) {
1594 twl4030->slave_substream = substream; 1680 twl4030->slave_substream = substream;
@@ -1619,7 +1705,7 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream,
1619 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1705 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1620 struct snd_soc_device *socdev = rtd->socdev; 1706 struct snd_soc_device *socdev = rtd->socdev;
1621 struct snd_soc_codec *codec = socdev->card->codec; 1707 struct snd_soc_codec *codec = socdev->card->codec;
1622 struct twl4030_priv *twl4030 = codec->private_data; 1708 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1623 1709
1624 if (twl4030->master_substream == substream) 1710 if (twl4030->master_substream == substream)
1625 twl4030->master_substream = twl4030->slave_substream; 1711 twl4030->master_substream = twl4030->slave_substream;
@@ -1645,7 +1731,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1645 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1731 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1646 struct snd_soc_device *socdev = rtd->socdev; 1732 struct snd_soc_device *socdev = rtd->socdev;
1647 struct snd_soc_codec *codec = socdev->card->codec; 1733 struct snd_soc_codec *codec = socdev->card->codec;
1648 struct twl4030_priv *twl4030 = codec->private_data; 1734 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1649 u8 mode, old_mode, format, old_format; 1735 u8 mode, old_mode, format, old_format;
1650 1736
1651 /* If the substream has 4 channel, do the necessary setup */ 1737 /* If the substream has 4 channel, do the necessary setup */
@@ -1765,7 +1851,7 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1765 int clk_id, unsigned int freq, int dir) 1851 int clk_id, unsigned int freq, int dir)
1766{ 1852{
1767 struct snd_soc_codec *codec = codec_dai->codec; 1853 struct snd_soc_codec *codec = codec_dai->codec;
1768 struct twl4030_priv *twl4030 = codec->private_data; 1854 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1769 1855
1770 switch (freq) { 1856 switch (freq) {
1771 case 19200000: 1857 case 19200000:
@@ -1880,7 +1966,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1880 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1966 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1881 struct snd_soc_device *socdev = rtd->socdev; 1967 struct snd_soc_device *socdev = rtd->socdev;
1882 struct snd_soc_codec *codec = socdev->card->codec; 1968 struct snd_soc_codec *codec = socdev->card->codec;
1883 struct twl4030_priv *twl4030 = codec->private_data; 1969 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1884 u8 mode; 1970 u8 mode;
1885 1971
1886 /* If the system master clock is not 26MHz, the voice PCM interface is 1972 /* If the system master clock is not 26MHz, the voice PCM interface is
@@ -1962,7 +2048,7 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1962 int clk_id, unsigned int freq, int dir) 2048 int clk_id, unsigned int freq, int dir)
1963{ 2049{
1964 struct snd_soc_codec *codec = codec_dai->codec; 2050 struct snd_soc_codec *codec = codec_dai->codec;
1965 struct twl4030_priv *twl4030 = codec->private_data; 2051 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1966 2052
1967 if (freq != 26000000) { 2053 if (freq != 26000000) {
1968 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" 2054 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
@@ -2108,7 +2194,6 @@ static int twl4030_soc_resume(struct platform_device *pdev)
2108 struct snd_soc_codec *codec = socdev->card->codec; 2194 struct snd_soc_codec *codec = socdev->card->codec;
2109 2195
2110 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2196 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2111 twl4030_set_bias_level(codec, codec->suspend_bias_level);
2112 return 0; 2197 return 0;
2113} 2198}
2114 2199
@@ -2125,7 +2210,7 @@ static int twl4030_soc_probe(struct platform_device *pdev)
2125 BUG_ON(!twl4030_codec); 2210 BUG_ON(!twl4030_codec);
2126 2211
2127 codec = twl4030_codec; 2212 codec = twl4030_codec;
2128 twl4030 = codec->private_data; 2213 twl4030 = snd_soc_codec_get_drvdata(codec);
2129 socdev->card->codec = codec; 2214 socdev->card->codec = codec;
2130 2215
2131 /* Configuration for headset ramp delay from setup data */ 2216 /* Configuration for headset ramp delay from setup data */
@@ -2188,7 +2273,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2188 } 2273 }
2189 2274
2190 codec = &twl4030->codec; 2275 codec = &twl4030->codec;
2191 codec->private_data = twl4030; 2276 snd_soc_codec_set_drvdata(codec, twl4030);
2192 codec->dev = &pdev->dev; 2277 codec->dev = &pdev->dev;
2193 twl4030_dai[0].dev = &pdev->dev; 2278 twl4030_dai[0].dev = &pdev->dev;
2194 twl4030_dai[1].dev = &pdev->dev; 2279 twl4030_dai[1].dev = &pdev->dev;
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
new file mode 100644
index 000000000000..af36346ff336
--- /dev/null
+++ b/sound/soc/codecs/twl6040.c
@@ -0,0 +1,1246 @@
1/*
2 * ALSA SoC TWL6040 codec driver
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/gpio.h>
29#include <linux/platform_device.h>
30#include <linux/slab.h>
31#include <linux/i2c/twl.h>
32
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37#include <sound/soc-dapm.h>
38#include <sound/initval.h>
39#include <sound/tlv.h>
40
41#include "twl6040.h"
42
43#define TWL6040_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
44#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
45
46/* codec private data */
47struct twl6040_data {
48 struct snd_soc_codec codec;
49 int audpwron;
50 int naudint;
51 int codec_powered;
52 int pll;
53 int non_lp;
54 unsigned int sysclk;
55 struct snd_pcm_hw_constraint_list *sysclk_constraints;
56 struct completion ready;
57};
58
59/*
60 * twl6040 register cache & default register settings
61 */
62static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = {
63 0x00, /* not used 0x00 */
64 0x4B, /* TWL6040_ASICID (ro) 0x01 */
65 0x00, /* TWL6040_ASICREV (ro) 0x02 */
66 0x00, /* TWL6040_INTID 0x03 */
67 0x00, /* TWL6040_INTMR 0x04 */
68 0x00, /* TWL6040_NCPCTRL 0x05 */
69 0x00, /* TWL6040_LDOCTL 0x06 */
70 0x60, /* TWL6040_HPPLLCTL 0x07 */
71 0x00, /* TWL6040_LPPLLCTL 0x08 */
72 0x4A, /* TWL6040_LPPLLDIV 0x09 */
73 0x00, /* TWL6040_AMICBCTL 0x0A */
74 0x00, /* TWL6040_DMICBCTL 0x0B */
75 0x18, /* TWL6040_MICLCTL 0x0C - No input selected on Left Mic */
76 0x18, /* TWL6040_MICRCTL 0x0D - No input selected on Right Mic */
77 0x00, /* TWL6040_MICGAIN 0x0E */
78 0x1B, /* TWL6040_LINEGAIN 0x0F */
79 0x00, /* TWL6040_HSLCTL 0x10 */
80 0x00, /* TWL6040_HSRCTL 0x11 */
81 0x00, /* TWL6040_HSGAIN 0x12 */
82 0x00, /* TWL6040_EARCTL 0x13 */
83 0x00, /* TWL6040_HFLCTL 0x14 */
84 0x00, /* TWL6040_HFLGAIN 0x15 */
85 0x00, /* TWL6040_HFRCTL 0x16 */
86 0x00, /* TWL6040_HFRGAIN 0x17 */
87 0x00, /* TWL6040_VIBCTLL 0x18 */
88 0x00, /* TWL6040_VIBDATL 0x19 */
89 0x00, /* TWL6040_VIBCTLR 0x1A */
90 0x00, /* TWL6040_VIBDATR 0x1B */
91 0x00, /* TWL6040_HKCTL1 0x1C */
92 0x00, /* TWL6040_HKCTL2 0x1D */
93 0x00, /* TWL6040_GPOCTL 0x1E */
94 0x00, /* TWL6040_ALB 0x1F */
95 0x00, /* TWL6040_DLB 0x20 */
96 0x00, /* not used 0x21 */
97 0x00, /* not used 0x22 */
98 0x00, /* not used 0x23 */
99 0x00, /* not used 0x24 */
100 0x00, /* not used 0x25 */
101 0x00, /* not used 0x26 */
102 0x00, /* not used 0x27 */
103 0x00, /* TWL6040_TRIM1 0x28 */
104 0x00, /* TWL6040_TRIM2 0x29 */
105 0x00, /* TWL6040_TRIM3 0x2A */
106 0x00, /* TWL6040_HSOTRIM 0x2B */
107 0x00, /* TWL6040_HFOTRIM 0x2C */
108 0x09, /* TWL6040_ACCCTL 0x2D */
109 0x00, /* TWL6040_STATUS (ro) 0x2E */
110};
111
112/*
113 * twl6040 vio/gnd registers:
114 * registers under vio/gnd supply can be accessed
115 * before the power-up sequence, after NRESPWRON goes high
116 */
117static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = {
118 TWL6040_REG_ASICID,
119 TWL6040_REG_ASICREV,
120 TWL6040_REG_INTID,
121 TWL6040_REG_INTMR,
122 TWL6040_REG_NCPCTL,
123 TWL6040_REG_LDOCTL,
124 TWL6040_REG_AMICBCTL,
125 TWL6040_REG_DMICBCTL,
126 TWL6040_REG_HKCTL1,
127 TWL6040_REG_HKCTL2,
128 TWL6040_REG_GPOCTL,
129 TWL6040_REG_TRIM1,
130 TWL6040_REG_TRIM2,
131 TWL6040_REG_TRIM3,
132 TWL6040_REG_HSOTRIM,
133 TWL6040_REG_HFOTRIM,
134 TWL6040_REG_ACCCTL,
135 TWL6040_REG_STATUS,
136};
137
138/*
139 * twl6040 vdd/vss registers:
140 * registers under vdd/vss supplies can only be accessed
141 * after the power-up sequence
142 */
143static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = {
144 TWL6040_REG_HPPLLCTL,
145 TWL6040_REG_LPPLLCTL,
146 TWL6040_REG_LPPLLDIV,
147 TWL6040_REG_MICLCTL,
148 TWL6040_REG_MICRCTL,
149 TWL6040_REG_MICGAIN,
150 TWL6040_REG_LINEGAIN,
151 TWL6040_REG_HSLCTL,
152 TWL6040_REG_HSRCTL,
153 TWL6040_REG_HSGAIN,
154 TWL6040_REG_EARCTL,
155 TWL6040_REG_HFLCTL,
156 TWL6040_REG_HFLGAIN,
157 TWL6040_REG_HFRCTL,
158 TWL6040_REG_HFRGAIN,
159 TWL6040_REG_VIBCTLL,
160 TWL6040_REG_VIBDATL,
161 TWL6040_REG_VIBCTLR,
162 TWL6040_REG_VIBDATR,
163 TWL6040_REG_ALB,
164 TWL6040_REG_DLB,
165};
166
167/*
168 * read twl6040 register cache
169 */
170static inline unsigned int twl6040_read_reg_cache(struct snd_soc_codec *codec,
171 unsigned int reg)
172{
173 u8 *cache = codec->reg_cache;
174
175 if (reg >= TWL6040_CACHEREGNUM)
176 return -EIO;
177
178 return cache[reg];
179}
180
181/*
182 * write twl6040 register cache
183 */
184static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec,
185 u8 reg, u8 value)
186{
187 u8 *cache = codec->reg_cache;
188
189 if (reg >= TWL6040_CACHEREGNUM)
190 return;
191 cache[reg] = value;
192}
193
194/*
195 * read from twl6040 hardware register
196 */
197static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
198 unsigned int reg)
199{
200 u8 value;
201
202 if (reg >= TWL6040_CACHEREGNUM)
203 return -EIO;
204
205 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg);
206 twl6040_write_reg_cache(codec, reg, value);
207
208 return value;
209}
210
211/*
212 * write to the twl6040 register space
213 */
214static int twl6040_write(struct snd_soc_codec *codec,
215 unsigned int reg, unsigned int value)
216{
217 if (reg >= TWL6040_CACHEREGNUM)
218 return -EIO;
219
220 twl6040_write_reg_cache(codec, reg, value);
221 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
222}
223
224static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
225{
226 u8 *cache = codec->reg_cache;
227 int reg, i;
228
229 /* allow registers to be accessed by i2c */
230 twl6040_write(codec, TWL6040_REG_ACCCTL, cache[TWL6040_REG_ACCCTL]);
231
232 for (i = 0; i < TWL6040_VIOREGNUM; i++) {
233 reg = twl6040_vio_reg[i];
234 /* skip read-only registers (ASICID, ASICREV, STATUS) */
235 switch (reg) {
236 case TWL6040_REG_ASICID:
237 case TWL6040_REG_ASICREV:
238 case TWL6040_REG_STATUS:
239 continue;
240 default:
241 break;
242 }
243 twl6040_write(codec, reg, cache[reg]);
244 }
245}
246
247static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
248{
249 u8 *cache = codec->reg_cache;
250 int reg, i;
251
252 for (i = 0; i < TWL6040_VDDREGNUM; i++) {
253 reg = twl6040_vdd_reg[i];
254 twl6040_write(codec, reg, cache[reg]);
255 }
256}
257
258/* twl6040 codec manual power-up sequence */
259static void twl6040_power_up(struct snd_soc_codec *codec)
260{
261 u8 ncpctl, ldoctl, lppllctl, accctl;
262
263 ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
264 ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
265 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
266 accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
267
268 /* enable reference system */
269 ldoctl |= TWL6040_REFENA;
270 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
271 msleep(10);
272 /* enable internal oscillator */
273 ldoctl |= TWL6040_OSCENA;
274 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
275 udelay(10);
276 /* enable high-side ldo */
277 ldoctl |= TWL6040_HSLDOENA;
278 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
279 udelay(244);
280 /* enable negative charge pump */
281 ncpctl |= TWL6040_NCPENA | TWL6040_NCPOPEN;
282 twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
283 udelay(488);
284 /* enable low-side ldo */
285 ldoctl |= TWL6040_LSLDOENA;
286 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
287 udelay(244);
288 /* enable low-power pll */
289 lppllctl |= TWL6040_LPLLENA;
290 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
291 /* reset state machine */
292 accctl |= TWL6040_RESETSPLIT;
293 twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
294 mdelay(5);
295 accctl &= ~TWL6040_RESETSPLIT;
296 twl6040_write(codec, TWL6040_REG_ACCCTL, accctl);
297 /* disable internal oscillator */
298 ldoctl &= ~TWL6040_OSCENA;
299 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
300}
301
302/* twl6040 codec manual power-down sequence */
303static void twl6040_power_down(struct snd_soc_codec *codec)
304{
305 u8 ncpctl, ldoctl, lppllctl, accctl;
306
307 ncpctl = twl6040_read_reg_cache(codec, TWL6040_REG_NCPCTL);
308 ldoctl = twl6040_read_reg_cache(codec, TWL6040_REG_LDOCTL);
309 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
310 accctl = twl6040_read_reg_cache(codec, TWL6040_REG_ACCCTL);
311
312 /* enable internal oscillator */
313 ldoctl |= TWL6040_OSCENA;
314 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
315 udelay(10);
316 /* disable low-power pll */
317 lppllctl &= ~TWL6040_LPLLENA;
318 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
319 /* disable low-side ldo */
320 ldoctl &= ~TWL6040_LSLDOENA;
321 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
322 udelay(244);
323 /* disable negative charge pump */
324 ncpctl &= ~(TWL6040_NCPENA | TWL6040_NCPOPEN);
325 twl6040_write(codec, TWL6040_REG_NCPCTL, ncpctl);
326 udelay(488);
327 /* disable high-side ldo */
328 ldoctl &= ~TWL6040_HSLDOENA;
329 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
330 udelay(244);
331 /* disable internal oscillator */
332 ldoctl &= ~TWL6040_OSCENA;
333 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
334 /* disable reference system */
335 ldoctl &= ~TWL6040_REFENA;
336 twl6040_write(codec, TWL6040_REG_LDOCTL, ldoctl);
337 msleep(10);
338}
339
340/* set headset dac and driver power mode */
341static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
342{
343 int hslctl, hsrctl;
344 int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL;
345
346 hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL);
347 hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL);
348
349 if (high_perf) {
350 hslctl &= ~mask;
351 hsrctl &= ~mask;
352 } else {
353 hslctl |= mask;
354 hsrctl |= mask;
355 }
356
357 twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl);
358 twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl);
359
360 return 0;
361}
362
363static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
364 struct snd_kcontrol *kcontrol, int event)
365{
366 struct snd_soc_codec *codec = w->codec;
367 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
368
369 if (SND_SOC_DAPM_EVENT_ON(event))
370 priv->non_lp++;
371 else
372 priv->non_lp--;
373
374 return 0;
375}
376
377/* audio interrupt handler */
378static irqreturn_t twl6040_naudint_handler(int irq, void *data)
379{
380 struct snd_soc_codec *codec = data;
381 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
382 u8 intid;
383
384 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
385
386 switch (intid) {
387 case TWL6040_THINT:
388 dev_alert(codec->dev, "die temp over-limit detection\n");
389 break;
390 case TWL6040_PLUGINT:
391 case TWL6040_UNPLUGINT:
392 case TWL6040_HOOKINT:
393 break;
394 case TWL6040_HFINT:
395 dev_alert(codec->dev, "hf drivers over current detection\n");
396 break;
397 case TWL6040_VIBINT:
398 dev_alert(codec->dev, "vib drivers over current detection\n");
399 break;
400 case TWL6040_READYINT:
401 complete(&priv->ready);
402 break;
403 default:
404 dev_err(codec->dev, "unknown audio interrupt %d\n", intid);
405 break;
406 }
407
408 return IRQ_HANDLED;
409}
410
411/*
412 * MICATT volume control:
413 * from -6 to 0 dB in 6 dB steps
414 */
415static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
416
417/*
418 * MICGAIN volume control:
419 * from 6 to 30 dB in 6 dB steps
420 */
421static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0);
422
423/*
424 * HSGAIN volume control:
425 * from -30 to 0 dB in 2 dB steps
426 */
427static DECLARE_TLV_DB_SCALE(hs_tlv, -3000, 200, 0);
428
429/*
430 * HFGAIN volume control:
431 * from -52 to 6 dB in 2 dB steps
432 */
433static DECLARE_TLV_DB_SCALE(hf_tlv, -5200, 200, 0);
434
435/*
436 * EPGAIN volume control:
437 * from -24 to 6 dB in 2 dB steps
438 */
439static DECLARE_TLV_DB_SCALE(ep_tlv, -2400, 200, 0);
440
441/* Left analog microphone selection */
442static const char *twl6040_amicl_texts[] =
443 {"Headset Mic", "Main Mic", "Aux/FM Left", "Off"};
444
445/* Right analog microphone selection */
446static const char *twl6040_amicr_texts[] =
447 {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
448
449static const struct soc_enum twl6040_enum[] = {
450 SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 3, twl6040_amicl_texts),
451 SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts),
452};
453
454static const struct snd_kcontrol_new amicl_control =
455 SOC_DAPM_ENUM("Route", twl6040_enum[0]);
456
457static const struct snd_kcontrol_new amicr_control =
458 SOC_DAPM_ENUM("Route", twl6040_enum[1]);
459
460/* Headset DAC playback switches */
461static const struct snd_kcontrol_new hsdacl_switch_controls =
462 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 5, 1, 0);
463
464static const struct snd_kcontrol_new hsdacr_switch_controls =
465 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 5, 1, 0);
466
467/* Handsfree DAC playback switches */
468static const struct snd_kcontrol_new hfdacl_switch_controls =
469 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 2, 1, 0);
470
471static const struct snd_kcontrol_new hfdacr_switch_controls =
472 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0);
473
474/* Headset driver switches */
475static const struct snd_kcontrol_new hsl_driver_switch_controls =
476 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 2, 1, 0);
477
478static const struct snd_kcontrol_new hsr_driver_switch_controls =
479 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 2, 1, 0);
480
481/* Handsfree driver switches */
482static const struct snd_kcontrol_new hfl_driver_switch_controls =
483 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 4, 1, 0);
484
485static const struct snd_kcontrol_new hfr_driver_switch_controls =
486 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 4, 1, 0);
487
488static const struct snd_kcontrol_new ep_driver_switch_controls =
489 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
490
491static const struct snd_kcontrol_new twl6040_snd_controls[] = {
492 /* Capture gains */
493 SOC_DOUBLE_TLV("Capture Preamplifier Volume",
494 TWL6040_REG_MICGAIN, 6, 7, 1, 1, mic_preamp_tlv),
495 SOC_DOUBLE_TLV("Capture Volume",
496 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
497
498 /* Playback gains */
499 SOC_DOUBLE_TLV("Headset Playback Volume",
500 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
501 SOC_DOUBLE_R_TLV("Handsfree Playback Volume",
502 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
503 SOC_SINGLE_TLV("Earphone Playback Volume",
504 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
505};
506
507static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
508 /* Inputs */
509 SND_SOC_DAPM_INPUT("MAINMIC"),
510 SND_SOC_DAPM_INPUT("HSMIC"),
511 SND_SOC_DAPM_INPUT("SUBMIC"),
512 SND_SOC_DAPM_INPUT("AFML"),
513 SND_SOC_DAPM_INPUT("AFMR"),
514
515 /* Outputs */
516 SND_SOC_DAPM_OUTPUT("HSOL"),
517 SND_SOC_DAPM_OUTPUT("HSOR"),
518 SND_SOC_DAPM_OUTPUT("HFL"),
519 SND_SOC_DAPM_OUTPUT("HFR"),
520 SND_SOC_DAPM_OUTPUT("EP"),
521
522 /* Analog input muxes for the capture amplifiers */
523 SND_SOC_DAPM_MUX("Analog Left Capture Route",
524 SND_SOC_NOPM, 0, 0, &amicl_control),
525 SND_SOC_DAPM_MUX("Analog Right Capture Route",
526 SND_SOC_NOPM, 0, 0, &amicr_control),
527
528 /* Analog capture PGAs */
529 SND_SOC_DAPM_PGA("MicAmpL",
530 TWL6040_REG_MICLCTL, 0, 0, NULL, 0),
531 SND_SOC_DAPM_PGA("MicAmpR",
532 TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
533
534 /* ADCs */
535 SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
536 TWL6040_REG_MICLCTL, 2, 0),
537 SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture",
538 TWL6040_REG_MICRCTL, 2, 0),
539
540 /* Microphone bias */
541 SND_SOC_DAPM_MICBIAS("Headset Mic Bias",
542 TWL6040_REG_AMICBCTL, 0, 0),
543 SND_SOC_DAPM_MICBIAS("Main Mic Bias",
544 TWL6040_REG_AMICBCTL, 4, 0),
545 SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias",
546 TWL6040_REG_DMICBCTL, 0, 0),
547 SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias",
548 TWL6040_REG_DMICBCTL, 4, 0),
549
550 /* DACs */
551 SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback",
552 TWL6040_REG_HSLCTL, 0, 0),
553 SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback",
554 TWL6040_REG_HSRCTL, 0, 0),
555 SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback",
556 TWL6040_REG_HFLCTL, 0, 0,
557 twl6040_power_mode_event,
558 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
559 SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback",
560 TWL6040_REG_HFRCTL, 0, 0,
561 twl6040_power_mode_event,
562 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
563
564 /* Analog playback switches */
565 SND_SOC_DAPM_SWITCH("HSDAC Left Playback",
566 SND_SOC_NOPM, 0, 0, &hsdacl_switch_controls),
567 SND_SOC_DAPM_SWITCH("HSDAC Right Playback",
568 SND_SOC_NOPM, 0, 0, &hsdacr_switch_controls),
569 SND_SOC_DAPM_SWITCH("HFDAC Left Playback",
570 SND_SOC_NOPM, 0, 0, &hfdacl_switch_controls),
571 SND_SOC_DAPM_SWITCH("HFDAC Right Playback",
572 SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls),
573
574 SND_SOC_DAPM_SWITCH("Headset Left Driver",
575 SND_SOC_NOPM, 0, 0, &hsl_driver_switch_controls),
576 SND_SOC_DAPM_SWITCH("Headset Right Driver",
577 SND_SOC_NOPM, 0, 0, &hsr_driver_switch_controls),
578 SND_SOC_DAPM_SWITCH_E("Handsfree Left Driver",
579 SND_SOC_NOPM, 0, 0, &hfl_driver_switch_controls,
580 twl6040_power_mode_event,
581 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
582 SND_SOC_DAPM_SWITCH_E("Handsfree Right Driver",
583 SND_SOC_NOPM, 0, 0, &hfr_driver_switch_controls,
584 twl6040_power_mode_event,
585 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
586 SND_SOC_DAPM_SWITCH_E("Earphone Driver",
587 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
588 twl6040_power_mode_event,
589 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
590
591 /* Analog playback PGAs */
592 SND_SOC_DAPM_PGA("HFDAC Left PGA",
593 TWL6040_REG_HFLCTL, 1, 0, NULL, 0),
594 SND_SOC_DAPM_PGA("HFDAC Right PGA",
595 TWL6040_REG_HFRCTL, 1, 0, NULL, 0),
596
597};
598
599static const struct snd_soc_dapm_route intercon[] = {
600 /* Capture path */
601 {"Analog Left Capture Route", "Headset Mic", "HSMIC"},
602 {"Analog Left Capture Route", "Main Mic", "MAINMIC"},
603 {"Analog Left Capture Route", "Aux/FM Left", "AFML"},
604
605 {"Analog Right Capture Route", "Headset Mic", "HSMIC"},
606 {"Analog Right Capture Route", "Sub Mic", "SUBMIC"},
607 {"Analog Right Capture Route", "Aux/FM Right", "AFMR"},
608
609 {"MicAmpL", NULL, "Analog Left Capture Route"},
610 {"MicAmpR", NULL, "Analog Right Capture Route"},
611
612 {"ADC Left", NULL, "MicAmpL"},
613 {"ADC Right", NULL, "MicAmpR"},
614
615 /* Headset playback path */
616 {"HSDAC Left Playback", "Switch", "HSDAC Left"},
617 {"HSDAC Right Playback", "Switch", "HSDAC Right"},
618
619 {"Headset Left Driver", "Switch", "HSDAC Left Playback"},
620 {"Headset Right Driver", "Switch", "HSDAC Right Playback"},
621
622 {"HSOL", NULL, "Headset Left Driver"},
623 {"HSOR", NULL, "Headset Right Driver"},
624
625 /* Earphone playback path */
626 {"Earphone Driver", "Switch", "HSDAC Left"},
627 {"EP", NULL, "Earphone Driver"},
628
629 /* Handsfree playback path */
630 {"HFDAC Left Playback", "Switch", "HFDAC Left"},
631 {"HFDAC Right Playback", "Switch", "HFDAC Right"},
632
633 {"HFDAC Left PGA", NULL, "HFDAC Left Playback"},
634 {"HFDAC Right PGA", NULL, "HFDAC Right Playback"},
635
636 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"},
637 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"},
638
639 {"HFL", NULL, "Handsfree Left Driver"},
640 {"HFR", NULL, "Handsfree Right Driver"},
641};
642
643static int twl6040_add_widgets(struct snd_soc_codec *codec)
644{
645 snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets,
646 ARRAY_SIZE(twl6040_dapm_widgets));
647
648 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
649
650 snd_soc_dapm_new_widgets(codec);
651
652 return 0;
653}
654
655static int twl6040_power_up_completion(struct snd_soc_codec *codec,
656 int naudint)
657{
658 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
659 int time_left;
660 u8 intid;
661
662 time_left = wait_for_completion_timeout(&priv->ready,
663 msecs_to_jiffies(48));
664
665 if (!time_left) {
666 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid,
667 TWL6040_REG_INTID);
668 if (!(intid & TWL6040_READYINT)) {
669 dev_err(codec->dev, "timeout waiting for READYINT\n");
670 return -ETIMEDOUT;
671 }
672 }
673
674 priv->codec_powered = 1;
675
676 return 0;
677}
678
679static int twl6040_set_bias_level(struct snd_soc_codec *codec,
680 enum snd_soc_bias_level level)
681{
682 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
683 int audpwron = priv->audpwron;
684 int naudint = priv->naudint;
685 int ret;
686
687 switch (level) {
688 case SND_SOC_BIAS_ON:
689 break;
690 case SND_SOC_BIAS_PREPARE:
691 break;
692 case SND_SOC_BIAS_STANDBY:
693 if (priv->codec_powered)
694 break;
695
696 if (gpio_is_valid(audpwron)) {
697 /* use AUDPWRON line */
698 gpio_set_value(audpwron, 1);
699
700 /* wait for power-up completion */
701 ret = twl6040_power_up_completion(codec, naudint);
702 if (ret)
703 return ret;
704
705 /* sync registers updated during power-up sequence */
706 twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
707 twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
708 twl6040_read_reg_volatile(codec, TWL6040_REG_LPPLLCTL);
709 } else {
710 /* use manual power-up sequence */
711 twl6040_power_up(codec);
712 priv->codec_powered = 1;
713 }
714
715 /* initialize vdd/vss registers with reg_cache */
716 twl6040_init_vdd_regs(codec);
717 break;
718 case SND_SOC_BIAS_OFF:
719 if (!priv->codec_powered)
720 break;
721
722 if (gpio_is_valid(audpwron)) {
723 /* use AUDPWRON line */
724 gpio_set_value(audpwron, 0);
725
726 /* power-down sequence latency */
727 udelay(500);
728
729 /* sync registers updated during power-down sequence */
730 twl6040_read_reg_volatile(codec, TWL6040_REG_NCPCTL);
731 twl6040_read_reg_volatile(codec, TWL6040_REG_LDOCTL);
732 twl6040_write_reg_cache(codec, TWL6040_REG_LPPLLCTL,
733 0x00);
734 } else {
735 /* use manual power-down sequence */
736 twl6040_power_down(codec);
737 }
738
739 priv->codec_powered = 0;
740 break;
741 }
742
743 codec->bias_level = level;
744
745 return 0;
746}
747
748/* set of rates for each pll: low-power and high-performance */
749
750static unsigned int lp_rates[] = {
751 88200,
752 96000,
753};
754
755static struct snd_pcm_hw_constraint_list lp_constraints = {
756 .count = ARRAY_SIZE(lp_rates),
757 .list = lp_rates,
758};
759
760static unsigned int hp_rates[] = {
761 96000,
762};
763
764static struct snd_pcm_hw_constraint_list hp_constraints = {
765 .count = ARRAY_SIZE(hp_rates),
766 .list = hp_rates,
767};
768
769static int twl6040_startup(struct snd_pcm_substream *substream,
770 struct snd_soc_dai *dai)
771{
772 struct snd_soc_pcm_runtime *rtd = substream->private_data;
773 struct snd_soc_device *socdev = rtd->socdev;
774 struct snd_soc_codec *codec = socdev->card->codec;
775 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
776
777 if (!priv->sysclk) {
778 dev_err(codec->dev,
779 "no mclk configured, call set_sysclk() on init\n");
780 return -EINVAL;
781 }
782
783 /*
784 * capture is not supported at 17.64 MHz,
785 * it's reserved for headset low-power playback scenario
786 */
787 if ((priv->sysclk == 17640000) && substream->stream) {
788 dev_err(codec->dev,
789 "capture mode is not supported at %dHz\n",
790 priv->sysclk);
791 return -EINVAL;
792 }
793
794 snd_pcm_hw_constraint_list(substream->runtime, 0,
795 SNDRV_PCM_HW_PARAM_RATE,
796 priv->sysclk_constraints);
797
798 return 0;
799}
800
801static int twl6040_hw_params(struct snd_pcm_substream *substream,
802 struct snd_pcm_hw_params *params,
803 struct snd_soc_dai *dai)
804{
805 struct snd_soc_pcm_runtime *rtd = substream->private_data;
806 struct snd_soc_device *socdev = rtd->socdev;
807 struct snd_soc_codec *codec = socdev->card->codec;
808 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
809 u8 lppllctl;
810 int rate;
811
812 /* nothing to do for high-perf pll, it supports only 48 kHz */
813 if (priv->pll == TWL6040_HPPLL_ID)
814 return 0;
815
816 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
817
818 rate = params_rate(params);
819 switch (rate) {
820 case 88200:
821 lppllctl |= TWL6040_LPLLFIN;
822 priv->sysclk = 17640000;
823 break;
824 case 96000:
825 lppllctl &= ~TWL6040_LPLLFIN;
826 priv->sysclk = 19200000;
827 break;
828 default:
829 dev_err(codec->dev, "unsupported rate %d\n", rate);
830 return -EINVAL;
831 }
832
833 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
834
835 return 0;
836}
837
838static int twl6040_trigger(struct snd_pcm_substream *substream,
839 int cmd, struct snd_soc_dai *dai)
840{
841 struct snd_soc_pcm_runtime *rtd = substream->private_data;
842 struct snd_soc_device *socdev = rtd->socdev;
843 struct snd_soc_codec *codec = socdev->card->codec;
844 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
845
846 switch (cmd) {
847 case SNDRV_PCM_TRIGGER_START:
848 case SNDRV_PCM_TRIGGER_RESUME:
849 /*
850 * low-power playback mode is restricted
851 * for headset path only
852 */
853 if ((priv->sysclk == 17640000) && priv->non_lp) {
854 dev_err(codec->dev,
855 "some enabled paths aren't supported at %dHz\n",
856 priv->sysclk);
857 return -EPERM;
858 }
859 break;
860 default:
861 break;
862 }
863
864 return 0;
865}
866
867static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
868 int clk_id, unsigned int freq, int dir)
869{
870 struct snd_soc_codec *codec = codec_dai->codec;
871 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
872 u8 hppllctl, lppllctl;
873
874 hppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_HPPLLCTL);
875 lppllctl = twl6040_read_reg_cache(codec, TWL6040_REG_LPPLLCTL);
876
877 switch (clk_id) {
878 case TWL6040_SYSCLK_SEL_LPPLL:
879 switch (freq) {
880 case 32768:
881 /* headset dac and driver must be in low-power mode */
882 headset_power_mode(codec, 0);
883
884 /* clk32k input requires low-power pll */
885 lppllctl |= TWL6040_LPLLENA;
886 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
887 mdelay(5);
888 lppllctl &= ~TWL6040_HPLLSEL;
889 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
890 hppllctl &= ~TWL6040_HPLLENA;
891 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
892 break;
893 default:
894 dev_err(codec->dev, "unknown mclk freq %d\n", freq);
895 return -EINVAL;
896 }
897
898 /* lppll divider */
899 switch (priv->sysclk) {
900 case 17640000:
901 lppllctl |= TWL6040_LPLLFIN;
902 break;
903 case 19200000:
904 lppllctl &= ~TWL6040_LPLLFIN;
905 break;
906 default:
907 /* sysclk not yet configured */
908 lppllctl &= ~TWL6040_LPLLFIN;
909 priv->sysclk = 19200000;
910 break;
911 }
912
913 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
914
915 priv->pll = TWL6040_LPPLL_ID;
916 priv->sysclk_constraints = &lp_constraints;
917 break;
918 case TWL6040_SYSCLK_SEL_HPPLL:
919 hppllctl &= ~TWL6040_MCLK_MSK;
920
921 switch (freq) {
922 case 12000000:
923 /* mclk input, pll enabled */
924 hppllctl |= TWL6040_MCLK_12000KHZ |
925 TWL6040_HPLLSQRBP |
926 TWL6040_HPLLENA;
927 break;
928 case 19200000:
929 /* mclk input, pll disabled */
930 hppllctl |= TWL6040_MCLK_19200KHZ |
931 TWL6040_HPLLSQRBP |
932 TWL6040_HPLLBP;
933 break;
934 case 26000000:
935 /* mclk input, pll enabled */
936 hppllctl |= TWL6040_MCLK_26000KHZ |
937 TWL6040_HPLLSQRBP |
938 TWL6040_HPLLENA;
939 break;
940 case 38400000:
941 /* clk slicer, pll disabled */
942 hppllctl |= TWL6040_MCLK_38400KHZ |
943 TWL6040_HPLLSQRENA |
944 TWL6040_HPLLBP;
945 break;
946 default:
947 dev_err(codec->dev, "unknown mclk freq %d\n", freq);
948 return -EINVAL;
949 }
950
951 /* headset dac and driver must be in high-performance mode */
952 headset_power_mode(codec, 1);
953
954 twl6040_write(codec, TWL6040_REG_HPPLLCTL, hppllctl);
955 udelay(500);
956 lppllctl |= TWL6040_HPLLSEL;
957 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
958 lppllctl &= ~TWL6040_LPLLENA;
959 twl6040_write(codec, TWL6040_REG_LPPLLCTL, lppllctl);
960
961 /* high-performance pll can provide only 19.2 MHz */
962 priv->pll = TWL6040_HPPLL_ID;
963 priv->sysclk = 19200000;
964 priv->sysclk_constraints = &hp_constraints;
965 break;
966 default:
967 dev_err(codec->dev, "unknown clk_id %d\n", clk_id);
968 return -EINVAL;
969 }
970
971 return 0;
972}
973
974static struct snd_soc_dai_ops twl6040_dai_ops = {
975 .startup = twl6040_startup,
976 .hw_params = twl6040_hw_params,
977 .trigger = twl6040_trigger,
978 .set_sysclk = twl6040_set_dai_sysclk,
979};
980
981struct snd_soc_dai twl6040_dai = {
982 .name = "twl6040",
983 .playback = {
984 .stream_name = "Playback",
985 .channels_min = 1,
986 .channels_max = 4,
987 .rates = TWL6040_RATES,
988 .formats = TWL6040_FORMATS,
989 },
990 .capture = {
991 .stream_name = "Capture",
992 .channels_min = 1,
993 .channels_max = 2,
994 .rates = TWL6040_RATES,
995 .formats = TWL6040_FORMATS,
996 },
997 .ops = &twl6040_dai_ops,
998};
999EXPORT_SYMBOL_GPL(twl6040_dai);
1000
1001#ifdef CONFIG_PM
1002static int twl6040_suspend(struct platform_device *pdev, pm_message_t state)
1003{
1004 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1005 struct snd_soc_codec *codec = socdev->card->codec;
1006
1007 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1008
1009 return 0;
1010}
1011
1012static int twl6040_resume(struct platform_device *pdev)
1013{
1014 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1015 struct snd_soc_codec *codec = socdev->card->codec;
1016
1017 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1018
1019 return 0;
1020}
1021#else
1022#define twl6040_suspend NULL
1023#define twl6040_resume NULL
1024#endif
1025
1026static struct snd_soc_codec *twl6040_codec;
1027
1028static int twl6040_probe(struct platform_device *pdev)
1029{
1030 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1031 struct snd_soc_codec *codec;
1032 int ret = 0;
1033
1034 BUG_ON(!twl6040_codec);
1035
1036 codec = twl6040_codec;
1037 socdev->card->codec = codec;
1038
1039 /* register pcms */
1040 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1041 if (ret < 0) {
1042 dev_err(&pdev->dev, "failed to create pcms\n");
1043 return ret;
1044 }
1045
1046 snd_soc_add_controls(codec, twl6040_snd_controls,
1047 ARRAY_SIZE(twl6040_snd_controls));
1048 twl6040_add_widgets(codec);
1049
1050 if (ret < 0) {
1051 dev_err(&pdev->dev, "failed to register card\n");
1052 goto card_err;
1053 }
1054
1055 return ret;
1056
1057card_err:
1058 snd_soc_free_pcms(socdev);
1059 snd_soc_dapm_free(socdev);
1060 return ret;
1061}
1062
1063static int twl6040_remove(struct platform_device *pdev)
1064{
1065 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1066 struct snd_soc_codec *codec = socdev->card->codec;
1067
1068 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1069 snd_soc_free_pcms(socdev);
1070 snd_soc_dapm_free(socdev);
1071 kfree(codec);
1072
1073 return 0;
1074}
1075
1076struct snd_soc_codec_device soc_codec_dev_twl6040 = {
1077 .probe = twl6040_probe,
1078 .remove = twl6040_remove,
1079 .suspend = twl6040_suspend,
1080 .resume = twl6040_resume,
1081};
1082EXPORT_SYMBOL_GPL(soc_codec_dev_twl6040);
1083
1084static int __devinit twl6040_codec_probe(struct platform_device *pdev)
1085{
1086 struct twl4030_codec_data *twl_codec = pdev->dev.platform_data;
1087 struct snd_soc_codec *codec;
1088 struct twl6040_data *priv;
1089 int audpwron, naudint;
1090 int ret = 0;
1091
1092 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
1093 if (priv == NULL)
1094 return -ENOMEM;
1095
1096 if (twl_codec) {
1097 audpwron = twl_codec->audpwron_gpio;
1098 naudint = twl_codec->naudint_irq;
1099 } else {
1100 audpwron = -EINVAL;
1101 naudint = 0;
1102 }
1103
1104 priv->audpwron = audpwron;
1105 priv->naudint = naudint;
1106
1107 codec = &priv->codec;
1108 codec->dev = &pdev->dev;
1109 twl6040_dai.dev = &pdev->dev;
1110
1111 codec->name = "twl6040";
1112 codec->owner = THIS_MODULE;
1113 codec->read = twl6040_read_reg_cache;
1114 codec->write = twl6040_write;
1115 codec->set_bias_level = twl6040_set_bias_level;
1116 snd_soc_codec_set_drvdata(codec, priv);
1117 codec->dai = &twl6040_dai;
1118 codec->num_dai = 1;
1119 codec->reg_cache_size = ARRAY_SIZE(twl6040_reg);
1120 codec->reg_cache = kmemdup(twl6040_reg, sizeof(twl6040_reg),
1121 GFP_KERNEL);
1122 if (codec->reg_cache == NULL) {
1123 ret = -ENOMEM;
1124 goto cache_err;
1125 }
1126
1127 mutex_init(&codec->mutex);
1128 INIT_LIST_HEAD(&codec->dapm_widgets);
1129 INIT_LIST_HEAD(&codec->dapm_paths);
1130 init_completion(&priv->ready);
1131
1132 if (gpio_is_valid(audpwron)) {
1133 ret = gpio_request(audpwron, "audpwron");
1134 if (ret)
1135 goto gpio1_err;
1136
1137 ret = gpio_direction_output(audpwron, 0);
1138 if (ret)
1139 goto gpio2_err;
1140
1141 priv->codec_powered = 0;
1142 }
1143
1144 if (naudint) {
1145 /* audio interrupt */
1146 ret = request_threaded_irq(naudint, NULL,
1147 twl6040_naudint_handler,
1148 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1149 "twl6040_codec", codec);
1150 if (ret)
1151 goto gpio2_err;
1152 } else {
1153 if (gpio_is_valid(audpwron)) {
1154 /* enable only codec ready interrupt */
1155 twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1156 ~TWL6040_READYMSK & TWL6040_ALLINT_MSK);
1157 } else {
1158 /* no interrupts at all */
1159 twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1160 TWL6040_ALLINT_MSK);
1161 }
1162 }
1163
1164 /* init vio registers */
1165 twl6040_init_vio_regs(codec);
1166
1167 /* power on device */
1168 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1169 if (ret)
1170 goto irq_err;
1171
1172 ret = snd_soc_register_codec(codec);
1173 if (ret)
1174 goto reg_err;
1175
1176 twl6040_codec = codec;
1177
1178 ret = snd_soc_register_dai(&twl6040_dai);
1179 if (ret)
1180 goto dai_err;
1181
1182 return 0;
1183
1184dai_err:
1185 snd_soc_unregister_codec(codec);
1186 twl6040_codec = NULL;
1187reg_err:
1188 twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF);
1189irq_err:
1190 if (naudint)
1191 free_irq(naudint, codec);
1192gpio2_err:
1193 if (gpio_is_valid(audpwron))
1194 gpio_free(audpwron);
1195gpio1_err:
1196 kfree(codec->reg_cache);
1197cache_err:
1198 kfree(priv);
1199 return ret;
1200}
1201
1202static int __devexit twl6040_codec_remove(struct platform_device *pdev)
1203{
1204 struct twl6040_data *priv = snd_soc_codec_get_drvdata(twl6040_codec);
1205 int audpwron = priv->audpwron;
1206 int naudint = priv->naudint;
1207
1208 if (gpio_is_valid(audpwron))
1209 gpio_free(audpwron);
1210
1211 if (naudint)
1212 free_irq(naudint, twl6040_codec);
1213
1214 snd_soc_unregister_dai(&twl6040_dai);
1215 snd_soc_unregister_codec(twl6040_codec);
1216
1217 kfree(twl6040_codec);
1218 twl6040_codec = NULL;
1219
1220 return 0;
1221}
1222
1223static struct platform_driver twl6040_codec_driver = {
1224 .driver = {
1225 .name = "twl6040_codec",
1226 .owner = THIS_MODULE,
1227 },
1228 .probe = twl6040_codec_probe,
1229 .remove = __devexit_p(twl6040_codec_remove),
1230};
1231
1232static int __init twl6040_codec_init(void)
1233{
1234 return platform_driver_register(&twl6040_codec_driver);
1235}
1236module_init(twl6040_codec_init);
1237
1238static void __exit twl6040_codec_exit(void)
1239{
1240 platform_driver_unregister(&twl6040_codec_driver);
1241}
1242module_exit(twl6040_codec_exit);
1243
1244MODULE_DESCRIPTION("ASoC TWL6040 codec driver");
1245MODULE_AUTHOR("Misael Lopez Cruz");
1246MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
new file mode 100644
index 000000000000..c472070a1da2
--- /dev/null
+++ b/sound/soc/codecs/twl6040.h
@@ -0,0 +1,141 @@
1/*
2 * ALSA SoC TWL6040 codec driver
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __TWL6040_H__
23#define __TWL6040_H__
24
25#define TWL6040_REG_ASICID 0x01
26#define TWL6040_REG_ASICREV 0x02
27#define TWL6040_REG_INTID 0x03
28#define TWL6040_REG_INTMR 0x04
29#define TWL6040_REG_NCPCTL 0x05
30#define TWL6040_REG_LDOCTL 0x06
31#define TWL6040_REG_HPPLLCTL 0x07
32#define TWL6040_REG_LPPLLCTL 0x08
33#define TWL6040_REG_LPPLLDIV 0x09
34#define TWL6040_REG_AMICBCTL 0x0A
35#define TWL6040_REG_DMICBCTL 0x0B
36#define TWL6040_REG_MICLCTL 0x0C
37#define TWL6040_REG_MICRCTL 0x0D
38#define TWL6040_REG_MICGAIN 0x0E
39#define TWL6040_REG_LINEGAIN 0x0F
40#define TWL6040_REG_HSLCTL 0x10
41#define TWL6040_REG_HSRCTL 0x11
42#define TWL6040_REG_HSGAIN 0x12
43#define TWL6040_REG_EARCTL 0x13
44#define TWL6040_REG_HFLCTL 0x14
45#define TWL6040_REG_HFLGAIN 0x15
46#define TWL6040_REG_HFRCTL 0x16
47#define TWL6040_REG_HFRGAIN 0x17
48#define TWL6040_REG_VIBCTLL 0x18
49#define TWL6040_REG_VIBDATL 0x19
50#define TWL6040_REG_VIBCTLR 0x1A
51#define TWL6040_REG_VIBDATR 0x1B
52#define TWL6040_REG_HKCTL1 0x1C
53#define TWL6040_REG_HKCTL2 0x1D
54#define TWL6040_REG_GPOCTL 0x1E
55#define TWL6040_REG_ALB 0x1F
56#define TWL6040_REG_DLB 0x20
57#define TWL6040_REG_TRIM1 0x28
58#define TWL6040_REG_TRIM2 0x29
59#define TWL6040_REG_TRIM3 0x2A
60#define TWL6040_REG_HSOTRIM 0x2B
61#define TWL6040_REG_HFOTRIM 0x2C
62#define TWL6040_REG_ACCCTL 0x2D
63#define TWL6040_REG_STATUS 0x2E
64
65#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1)
66
67#define TWL6040_VIOREGNUM 18
68#define TWL6040_VDDREGNUM 21
69
70/* INTID (0x03) fields */
71
72#define TWL6040_THINT 0x01
73#define TWL6040_PLUGINT 0x02
74#define TWL6040_UNPLUGINT 0x04
75#define TWL6040_HOOKINT 0x08
76#define TWL6040_HFINT 0x10
77#define TWL6040_VIBINT 0x20
78#define TWL6040_READYINT 0x40
79
80/* INTMR (0x04) fields */
81
82#define TWL6040_READYMSK 0x40
83#define TWL6040_ALLINT_MSK 0x7B
84
85/* NCPCTL (0x05) fields */
86
87#define TWL6040_NCPENA 0x01
88#define TWL6040_NCPOPEN 0x40
89
90/* LDOCTL (0x06) fields */
91
92#define TWL6040_LSLDOENA 0x01
93#define TWL6040_HSLDOENA 0x04
94#define TWL6040_REFENA 0x40
95#define TWL6040_OSCENA 0x80
96
97/* HPPLLCTL (0x07) fields */
98
99#define TWL6040_HPLLENA 0x01
100#define TWL6040_HPLLRST 0x02
101#define TWL6040_HPLLBP 0x04
102#define TWL6040_HPLLSQRENA 0x08
103#define TWL6040_HPLLSQRBP 0x10
104#define TWL6040_MCLK_12000KHZ (0 << 5)
105#define TWL6040_MCLK_19200KHZ (1 << 5)
106#define TWL6040_MCLK_26000KHZ (2 << 5)
107#define TWL6040_MCLK_38400KHZ (3 << 5)
108#define TWL6040_MCLK_MSK 0x60
109
110/* LPPLLCTL (0x08) fields */
111
112#define TWL6040_LPLLENA 0x01
113#define TWL6040_LPLLRST 0x02
114#define TWL6040_LPLLSEL 0x04
115#define TWL6040_LPLLFIN 0x08
116#define TWL6040_HPLLSEL 0x10
117
118/* HSLCTL (0x10) fields */
119
120#define TWL6040_HSDACMODEL 0x02
121#define TWL6040_HSDRVMODEL 0x08
122
123/* HSRCTL (0x11) fields */
124
125#define TWL6040_HSDACMODER 0x02
126#define TWL6040_HSDRVMODER 0x08
127
128/* ACCCTL (0x2D) fields */
129
130#define TWL6040_RESETSPLIT 0x04
131
132#define TWL6040_SYSCLK_SEL_LPPLL 1
133#define TWL6040_SYSCLK_SEL_HPPLL 2
134
135#define TWL6040_HPPLL_ID 1
136#define TWL6040_LPPLL_ID 2
137
138extern struct snd_soc_dai twl6040_dai;
139extern struct snd_soc_codec_device soc_codec_dev_twl6040;
140
141#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index a8dcd5a5bbcb..28aac53c97bb 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -175,7 +175,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
175 struct snd_soc_pcm_runtime *rtd = substream->private_data; 175 struct snd_soc_pcm_runtime *rtd = substream->private_data;
176 struct snd_soc_device *socdev = rtd->socdev; 176 struct snd_soc_device *socdev = rtd->socdev;
177 struct snd_soc_codec *codec = socdev->card->codec; 177 struct snd_soc_codec *codec = socdev->card->codec;
178 struct uda134x_priv *uda134x = codec->private_data; 178 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
179 struct snd_pcm_runtime *master_runtime; 179 struct snd_pcm_runtime *master_runtime;
180 180
181 if (uda134x->master_substream) { 181 if (uda134x->master_substream) {
@@ -208,7 +208,7 @@ static void uda134x_shutdown(struct snd_pcm_substream *substream,
208 struct snd_soc_pcm_runtime *rtd = substream->private_data; 208 struct snd_soc_pcm_runtime *rtd = substream->private_data;
209 struct snd_soc_device *socdev = rtd->socdev; 209 struct snd_soc_device *socdev = rtd->socdev;
210 struct snd_soc_codec *codec = socdev->card->codec; 210 struct snd_soc_codec *codec = socdev->card->codec;
211 struct uda134x_priv *uda134x = codec->private_data; 211 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
212 212
213 if (uda134x->master_substream == substream) 213 if (uda134x->master_substream == substream)
214 uda134x->master_substream = uda134x->slave_substream; 214 uda134x->master_substream = uda134x->slave_substream;
@@ -223,7 +223,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream,
223 struct snd_soc_pcm_runtime *rtd = substream->private_data; 223 struct snd_soc_pcm_runtime *rtd = substream->private_data;
224 struct snd_soc_device *socdev = rtd->socdev; 224 struct snd_soc_device *socdev = rtd->socdev;
225 struct snd_soc_codec *codec = socdev->card->codec; 225 struct snd_soc_codec *codec = socdev->card->codec;
226 struct uda134x_priv *uda134x = codec->private_data; 226 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
227 u8 hw_params; 227 u8 hw_params;
228 228
229 if (substream == uda134x->slave_substream) { 229 if (substream == uda134x->slave_substream) {
@@ -295,7 +295,7 @@ static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
295 int clk_id, unsigned int freq, int dir) 295 int clk_id, unsigned int freq, int dir)
296{ 296{
297 struct snd_soc_codec *codec = codec_dai->codec; 297 struct snd_soc_codec *codec = codec_dai->codec;
298 struct uda134x_priv *uda134x = codec->private_data; 298 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
299 299
300 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__, 300 pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__,
301 clk_id, freq, dir); 301 clk_id, freq, dir);
@@ -317,7 +317,7 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
317 unsigned int fmt) 317 unsigned int fmt)
318{ 318{
319 struct snd_soc_codec *codec = codec_dai->codec; 319 struct snd_soc_codec *codec = codec_dai->codec;
320 struct uda134x_priv *uda134x = codec->private_data; 320 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
321 321
322 pr_debug("%s fmt: %08X\n", __func__, fmt); 322 pr_debug("%s fmt: %08X\n", __func__, fmt);
323 323
@@ -432,6 +432,14 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
432SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), 432SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
433}; 433};
434 434
435static const struct snd_kcontrol_new uda1345_snd_controls[] = {
436SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
437
438SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
439
440SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
441};
442
435static struct snd_soc_dai_ops uda134x_dai_ops = { 443static struct snd_soc_dai_ops uda134x_dai_ops = {
436 .startup = uda134x_startup, 444 .startup = uda134x_startup,
437 .shutdown = uda134x_shutdown, 445 .shutdown = uda134x_shutdown,
@@ -487,6 +495,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
487 case UDA134X_UDA1340: 495 case UDA134X_UDA1340:
488 case UDA134X_UDA1341: 496 case UDA134X_UDA1341:
489 case UDA134X_UDA1344: 497 case UDA134X_UDA1344:
498 case UDA134X_UDA1345:
490 break; 499 break;
491 default: 500 default:
492 printk(KERN_ERR "UDA134X SoC codec: " 501 printk(KERN_ERR "UDA134X SoC codec: "
@@ -504,7 +513,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
504 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); 513 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
505 if (uda134x == NULL) 514 if (uda134x == NULL)
506 goto priv_err; 515 goto priv_err;
507 codec->private_data = uda134x; 516 snd_soc_codec_set_drvdata(codec, uda134x);
508 517
509 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg), 518 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
510 GFP_KERNEL); 519 GFP_KERNEL);
@@ -552,6 +561,10 @@ static int uda134x_soc_probe(struct platform_device *pdev)
552 ret = snd_soc_add_controls(codec, uda1341_snd_controls, 561 ret = snd_soc_add_controls(codec, uda1341_snd_controls,
553 ARRAY_SIZE(uda1341_snd_controls)); 562 ARRAY_SIZE(uda1341_snd_controls));
554 break; 563 break;
564 case UDA134X_UDA1345:
565 ret = snd_soc_add_controls(codec, uda1345_snd_controls,
566 ARRAY_SIZE(uda1345_snd_controls));
567 break;
555 default: 568 default:
556 printk(KERN_ERR "%s unknown codec type: %d", 569 printk(KERN_ERR "%s unknown codec type: %d",
557 __func__, pd->model); 570 __func__, pd->model);
@@ -568,7 +581,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
568pcm_err: 581pcm_err:
569 kfree(codec->reg_cache); 582 kfree(codec->reg_cache);
570reg_err: 583reg_err:
571 kfree(codec->private_data); 584 kfree(snd_soc_codec_get_drvdata(codec));
572priv_err: 585priv_err:
573 kfree(codec); 586 kfree(codec);
574 return ret; 587 return ret;
@@ -586,7 +599,7 @@ static int uda134x_soc_remove(struct platform_device *pdev)
586 snd_soc_free_pcms(socdev); 599 snd_soc_free_pcms(socdev);
587 snd_soc_dapm_free(socdev); 600 snd_soc_dapm_free(socdev);
588 601
589 kfree(codec->private_data); 602 kfree(snd_soc_codec_get_drvdata(codec));
590 kfree(codec->reg_cache); 603 kfree(codec->reg_cache);
591 kfree(codec); 604 kfree(codec);
592 605
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 9cd0a66b7663..2f925a27dcde 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -476,7 +476,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
476 struct snd_soc_pcm_runtime *rtd = substream->private_data; 476 struct snd_soc_pcm_runtime *rtd = substream->private_data;
477 struct snd_soc_device *socdev = rtd->socdev; 477 struct snd_soc_device *socdev = rtd->socdev;
478 struct snd_soc_codec *codec = socdev->card->codec; 478 struct snd_soc_codec *codec = socdev->card->codec;
479 struct uda1380_priv *uda1380 = codec->private_data; 479 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
480 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); 480 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
481 481
482 switch (cmd) { 482 switch (cmd) {
@@ -670,7 +670,6 @@ static int uda1380_resume(struct platform_device *pdev)
670 codec->hw_write(codec->control_data, data, 2); 670 codec->hw_write(codec->control_data, data, 2);
671 } 671 }
672 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 672 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
673 uda1380_set_bias_level(codec, codec->suspend_bias_level);
674 return 0; 673 return 0;
675} 674}
676 675
@@ -774,7 +773,7 @@ static int uda1380_register(struct uda1380_priv *uda1380)
774 INIT_LIST_HEAD(&codec->dapm_widgets); 773 INIT_LIST_HEAD(&codec->dapm_widgets);
775 INIT_LIST_HEAD(&codec->dapm_paths); 774 INIT_LIST_HEAD(&codec->dapm_paths);
776 775
777 codec->private_data = uda1380; 776 snd_soc_codec_set_drvdata(codec, uda1380);
778 codec->name = "UDA1380"; 777 codec->name = "UDA1380";
779 codec->owner = THIS_MODULE; 778 codec->owner = THIS_MODULE;
780 codec->read = uda1380_read_reg_cache; 779 codec->read = uda1380_read_reg_cache;
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 2e0772f9c456..8ae20208e7be 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -55,6 +55,7 @@ struct wm8350_output {
55struct wm8350_jack_data { 55struct wm8350_jack_data {
56 struct snd_soc_jack *jack; 56 struct snd_soc_jack *jack;
57 int report; 57 int report;
58 int short_report;
58}; 59};
59 60
60struct wm8350_data { 61struct wm8350_data {
@@ -63,6 +64,7 @@ struct wm8350_data {
63 struct wm8350_output out2; 64 struct wm8350_output out2;
64 struct wm8350_jack_data hpl; 65 struct wm8350_jack_data hpl;
65 struct wm8350_jack_data hpr; 66 struct wm8350_jack_data hpr;
67 struct wm8350_jack_data mic;
66 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 68 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
67 int fll_freq_out; 69 int fll_freq_out;
68 int fll_freq_in; 70 int fll_freq_in;
@@ -94,7 +96,7 @@ static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
94 */ 96 */
95static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec) 97static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
96{ 98{
97 struct wm8350_data *wm8350_data = codec->private_data; 99 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
98 struct wm8350_output *out1 = &wm8350_data->out1; 100 struct wm8350_output *out1 = &wm8350_data->out1;
99 struct wm8350 *wm8350 = codec->control_data; 101 struct wm8350 *wm8350 = codec->control_data;
100 int left_complete = 0, right_complete = 0; 102 int left_complete = 0, right_complete = 0;
@@ -160,7 +162,7 @@ static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
160 */ 162 */
161static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) 163static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
162{ 164{
163 struct wm8350_data *wm8350_data = codec->private_data; 165 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
164 struct wm8350_output *out2 = &wm8350_data->out2; 166 struct wm8350_output *out2 = &wm8350_data->out2;
165 struct wm8350 *wm8350 = codec->control_data; 167 struct wm8350 *wm8350 = codec->control_data;
166 int left_complete = 0, right_complete = 0; 168 int left_complete = 0, right_complete = 0;
@@ -230,7 +232,7 @@ static void wm8350_pga_work(struct work_struct *work)
230{ 232{
231 struct snd_soc_codec *codec = 233 struct snd_soc_codec *codec =
232 container_of(work, struct snd_soc_codec, delayed_work.work); 234 container_of(work, struct snd_soc_codec, delayed_work.work);
233 struct wm8350_data *wm8350_data = codec->private_data; 235 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
234 struct wm8350_output *out1 = &wm8350_data->out1, 236 struct wm8350_output *out1 = &wm8350_data->out1,
235 *out2 = &wm8350_data->out2; 237 *out2 = &wm8350_data->out2;
236 int i, out1_complete, out2_complete; 238 int i, out1_complete, out2_complete;
@@ -277,7 +279,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
277 struct snd_kcontrol *kcontrol, int event) 279 struct snd_kcontrol *kcontrol, int event)
278{ 280{
279 struct snd_soc_codec *codec = w->codec; 281 struct snd_soc_codec *codec = w->codec;
280 struct wm8350_data *wm8350_data = codec->private_data; 282 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
281 struct wm8350_output *out; 283 struct wm8350_output *out;
282 284
283 switch (w->shift) { 285 switch (w->shift) {
@@ -322,7 +324,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
322 struct snd_ctl_elem_value *ucontrol) 324 struct snd_ctl_elem_value *ucontrol)
323{ 325{
324 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 326 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
325 struct wm8350_data *wm8350_priv = codec->private_data; 327 struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
326 struct wm8350_output *out = NULL; 328 struct wm8350_output *out = NULL;
327 struct soc_mixer_control *mc = 329 struct soc_mixer_control *mc =
328 (struct soc_mixer_control *)kcontrol->private_value; 330 (struct soc_mixer_control *)kcontrol->private_value;
@@ -365,7 +367,7 @@ static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
365 struct snd_ctl_elem_value *ucontrol) 367 struct snd_ctl_elem_value *ucontrol)
366{ 368{
367 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 369 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
368 struct wm8350_data *wm8350_priv = codec->private_data; 370 struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec);
369 struct wm8350_output *out1 = &wm8350_priv->out1; 371 struct wm8350_output *out1 = &wm8350_priv->out1;
370 struct wm8350_output *out2 = &wm8350_priv->out2; 372 struct wm8350_output *out2 = &wm8350_priv->out2;
371 struct soc_mixer_control *mc = 373 struct soc_mixer_control *mc =
@@ -1107,7 +1109,7 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1107{ 1109{
1108 struct snd_soc_codec *codec = codec_dai->codec; 1110 struct snd_soc_codec *codec = codec_dai->codec;
1109 struct wm8350 *wm8350 = codec->control_data; 1111 struct wm8350 *wm8350 = codec->control_data;
1110 struct wm8350_data *priv = codec->private_data; 1112 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1111 struct _fll_div fll_div; 1113 struct _fll_div fll_div;
1112 int ret = 0; 1114 int ret = 0;
1113 u16 fll_1, fll_4; 1115 u16 fll_1, fll_4;
@@ -1159,7 +1161,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1159 enum snd_soc_bias_level level) 1161 enum snd_soc_bias_level level)
1160{ 1162{
1161 struct wm8350 *wm8350 = codec->control_data; 1163 struct wm8350 *wm8350 = codec->control_data;
1162 struct wm8350_data *priv = codec->private_data; 1164 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1163 struct wm8350_audio_platform_data *platform = 1165 struct wm8350_audio_platform_data *platform =
1164 wm8350->codec.platform_data; 1166 wm8350->codec.platform_data;
1165 u16 pm1; 1167 u16 pm1;
@@ -1335,9 +1337,6 @@ static int wm8350_resume(struct platform_device *pdev)
1335 1337
1336 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1338 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1337 1339
1338 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1339 wm8350_set_bias_level(codec, SND_SOC_BIAS_ON);
1340
1341 return 0; 1340 return 0;
1342} 1341}
1343 1342
@@ -1392,12 +1391,13 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1392 * @jack: jack to report detection events on 1391 * @jack: jack to report detection events on
1393 * @report: value to report 1392 * @report: value to report
1394 * 1393 *
1395 * Enables the headphone jack detection of the WM8350. 1394 * Enables the headphone jack detection of the WM8350. If no report
1395 * is specified then detection is disabled.
1396 */ 1396 */
1397int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, 1397int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1398 struct snd_soc_jack *jack, int report) 1398 struct snd_soc_jack *jack, int report)
1399{ 1399{
1400 struct wm8350_data *priv = codec->private_data; 1400 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1401 struct wm8350 *wm8350 = codec->control_data; 1401 struct wm8350 *wm8350 = codec->control_data;
1402 int irq; 1402 int irq;
1403 int ena; 1403 int ena;
@@ -1421,8 +1421,12 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1421 return -EINVAL; 1421 return -EINVAL;
1422 } 1422 }
1423 1423
1424 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1424 if (report) {
1425 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); 1425 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1426 wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena);
1427 } else {
1428 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, ena);
1429 }
1426 1430
1427 /* Sync status */ 1431 /* Sync status */
1428 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv); 1432 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv);
@@ -1431,6 +1435,60 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1431} 1435}
1432EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); 1436EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect);
1433 1437
1438static irqreturn_t wm8350_mic_handler(int irq, void *data)
1439{
1440 struct wm8350_data *priv = data;
1441 struct wm8350 *wm8350 = priv->codec.control_data;
1442 u16 reg;
1443 int report = 0;
1444
1445 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1446 if (reg & WM8350_JACK_MICSCD_LVL)
1447 report |= priv->mic.short_report;
1448 if (reg & WM8350_JACK_MICSD_LVL)
1449 report |= priv->mic.report;
1450
1451 snd_soc_jack_report(priv->mic.jack, report,
1452 priv->mic.report | priv->mic.short_report);
1453
1454 return IRQ_HANDLED;
1455}
1456
1457/**
1458 * wm8350_mic_jack_detect - Enable microphone jack detection.
1459 *
1460 * @codec: WM8350 codec
1461 * @jack: jack to report detection events on
1462 * @detect_report: value to report when presence detected
1463 * @short_report: value to report when microphone short detected
1464 *
1465 * Enables the microphone jack detection of the WM8350. If both reports
1466 * are specified as zero then detection is disabled.
1467 */
1468int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
1469 struct snd_soc_jack *jack,
1470 int detect_report, int short_report)
1471{
1472 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1473 struct wm8350 *wm8350 = codec->control_data;
1474
1475 priv->mic.jack = jack;
1476 priv->mic.report = detect_report;
1477 priv->mic.short_report = short_report;
1478
1479 if (detect_report || short_report) {
1480 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1481 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_1,
1482 WM8350_MIC_DET_ENA);
1483 } else {
1484 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_1,
1485 WM8350_MIC_DET_ENA);
1486 }
1487
1488 return 0;
1489}
1490EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
1491
1434static struct snd_soc_codec *wm8350_codec; 1492static struct snd_soc_codec *wm8350_codec;
1435 1493
1436static int wm8350_probe(struct platform_device *pdev) 1494static int wm8350_probe(struct platform_device *pdev)
@@ -1448,7 +1506,7 @@ static int wm8350_probe(struct platform_device *pdev)
1448 socdev->card->codec = wm8350_codec; 1506 socdev->card->codec = wm8350_codec;
1449 codec = socdev->card->codec; 1507 codec = socdev->card->codec;
1450 wm8350 = codec->control_data; 1508 wm8350 = codec->control_data;
1451 priv = codec->private_data; 1509 priv = snd_soc_codec_get_drvdata(codec);
1452 1510
1453 /* Enable the codec */ 1511 /* Enable the codec */
1454 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1512 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1494,6 +1552,10 @@ static int wm8350_probe(struct platform_device *pdev)
1494 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, 1552 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
1495 wm8350_hp_jack_handler, 0, "Right jack detect", 1553 wm8350_hp_jack_handler, 0, "Right jack detect",
1496 priv); 1554 priv);
1555 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD,
1556 wm8350_mic_handler, 0, "Microphone short", priv);
1557 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD,
1558 wm8350_mic_handler, 0, "Microphone detect", priv);
1497 1559
1498 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1560 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1499 if (ret < 0) { 1561 if (ret < 0) {
@@ -1515,18 +1577,21 @@ static int wm8350_remove(struct platform_device *pdev)
1515 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1577 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1516 struct snd_soc_codec *codec = socdev->card->codec; 1578 struct snd_soc_codec *codec = socdev->card->codec;
1517 struct wm8350 *wm8350 = codec->control_data; 1579 struct wm8350 *wm8350 = codec->control_data;
1518 struct wm8350_data *priv = codec->private_data; 1580 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1519 int ret; 1581 int ret;
1520 1582
1521 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1583 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1522 WM8350_JDL_ENA | WM8350_JDR_ENA); 1584 WM8350_JDL_ENA | WM8350_JDR_ENA);
1523 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); 1585 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);
1524 1586
1587 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICD, priv);
1588 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv);
1525 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv); 1589 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv);
1526 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv); 1590 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv);
1527 1591
1528 priv->hpl.jack = NULL; 1592 priv->hpl.jack = NULL;
1529 priv->hpr.jack = NULL; 1593 priv->hpr.jack = NULL;
1594 priv->mic.jack = NULL;
1530 1595
1531 /* cancel any work waiting to be queued. */ 1596 /* cancel any work waiting to be queued. */
1532 ret = cancel_delayed_work(&codec->delayed_work); 1597 ret = cancel_delayed_work(&codec->delayed_work);
@@ -1631,7 +1696,7 @@ static __devinit int wm8350_codec_probe(struct platform_device *pdev)
1631 codec->dai = &wm8350_dai; 1696 codec->dai = &wm8350_dai;
1632 codec->num_dai = 1; 1697 codec->num_dai = 1;
1633 codec->reg_cache_size = WM8350_MAX_REGISTER; 1698 codec->reg_cache_size = WM8350_MAX_REGISTER;
1634 codec->private_data = priv; 1699 snd_soc_codec_set_drvdata(codec, priv);
1635 codec->control_data = wm8350; 1700 codec->control_data = wm8350;
1636 1701
1637 /* Put the codec into reset if it wasn't already */ 1702 /* Put the codec into reset if it wasn't already */
@@ -1663,7 +1728,7 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1663{ 1728{
1664 struct wm8350 *wm8350 = platform_get_drvdata(pdev); 1729 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1665 struct snd_soc_codec *codec = wm8350->codec.codec; 1730 struct snd_soc_codec *codec = wm8350->codec.codec;
1666 struct wm8350_data *priv = codec->private_data; 1731 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1667 1732
1668 snd_soc_unregister_dai(&wm8350_dai); 1733 snd_soc_unregister_dai(&wm8350_dai);
1669 snd_soc_unregister_codec(codec); 1734 snd_soc_unregister_codec(codec);
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
index d088eb4b88bb..9ed0467c71db 100644
--- a/sound/soc/codecs/wm8350.h
+++ b/sound/soc/codecs/wm8350.h
@@ -25,5 +25,8 @@ enum wm8350_jack {
25 25
26int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, 26int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
27 struct snd_soc_jack *jack, int report); 27 struct snd_soc_jack *jack, int report);
28int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
29 struct snd_soc_jack *jack,
30 int detect_report, int short_report);
28 31
29#endif 32#endif
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 6acc885cf9b7..7f5d080536a0 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -77,7 +77,7 @@ struct wm8400_priv {
77static inline unsigned int wm8400_read(struct snd_soc_codec *codec, 77static inline unsigned int wm8400_read(struct snd_soc_codec *codec,
78 unsigned int reg) 78 unsigned int reg)
79{ 79{
80 struct wm8400_priv *wm8400 = codec->private_data; 80 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
81 81
82 if (reg == WM8400_INTDRIVBITS) 82 if (reg == WM8400_INTDRIVBITS)
83 return wm8400->fake_register; 83 return wm8400->fake_register;
@@ -91,7 +91,7 @@ static inline unsigned int wm8400_read(struct snd_soc_codec *codec,
91static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg, 91static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg,
92 unsigned int value) 92 unsigned int value)
93{ 93{
94 struct wm8400_priv *wm8400 = codec->private_data; 94 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
95 95
96 if (reg == WM8400_INTDRIVBITS) { 96 if (reg == WM8400_INTDRIVBITS) {
97 wm8400->fake_register = value; 97 wm8400->fake_register = value;
@@ -102,7 +102,7 @@ static int wm8400_write(struct snd_soc_codec *codec, unsigned int reg,
102 102
103static void wm8400_codec_reset(struct snd_soc_codec *codec) 103static void wm8400_codec_reset(struct snd_soc_codec *codec)
104{ 104{
105 struct wm8400_priv *wm8400 = codec->private_data; 105 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
106 106
107 wm8400_reset_codec_reg_cache(wm8400->wm8400); 107 wm8400_reset_codec_reg_cache(wm8400->wm8400);
108} 108}
@@ -926,7 +926,7 @@ static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai,
926 int clk_id, unsigned int freq, int dir) 926 int clk_id, unsigned int freq, int dir)
927{ 927{
928 struct snd_soc_codec *codec = codec_dai->codec; 928 struct snd_soc_codec *codec = codec_dai->codec;
929 struct wm8400_priv *wm8400 = codec->private_data; 929 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
930 930
931 wm8400->sysclk = freq; 931 wm8400->sysclk = freq;
932 return 0; 932 return 0;
@@ -1015,7 +1015,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1015 unsigned int freq_out) 1015 unsigned int freq_out)
1016{ 1016{
1017 struct snd_soc_codec *codec = codec_dai->codec; 1017 struct snd_soc_codec *codec = codec_dai->codec;
1018 struct wm8400_priv *wm8400 = codec->private_data; 1018 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
1019 struct fll_factors factors; 1019 struct fll_factors factors;
1020 int ret; 1020 int ret;
1021 u16 reg; 1021 u16 reg;
@@ -1204,7 +1204,7 @@ static int wm8400_mute(struct snd_soc_dai *dai, int mute)
1204static int wm8400_set_bias_level(struct snd_soc_codec *codec, 1204static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1205 enum snd_soc_bias_level level) 1205 enum snd_soc_bias_level level)
1206{ 1206{
1207 struct wm8400_priv *wm8400 = codec->private_data; 1207 struct wm8400_priv *wm8400 = snd_soc_codec_get_drvdata(codec);
1208 u16 val; 1208 u16 val;
1209 int ret; 1209 int ret;
1210 1210
@@ -1467,7 +1467,7 @@ static int wm8400_codec_probe(struct platform_device *dev)
1467 return -ENOMEM; 1467 return -ENOMEM;
1468 1468
1469 codec = &priv->codec; 1469 codec = &priv->codec;
1470 codec->private_data = priv; 1470 snd_soc_codec_set_drvdata(codec, priv);
1471 codec->control_data = dev_get_drvdata(&dev->dev); 1471 codec->control_data = dev_get_drvdata(&dev->dev);
1472 priv->wm8400 = dev_get_drvdata(&dev->dev); 1472 priv->wm8400 = dev_get_drvdata(&dev->dev);
1473 1473
@@ -1530,7 +1530,7 @@ err:
1530 1530
1531static int __exit wm8400_codec_remove(struct platform_device *dev) 1531static int __exit wm8400_codec_remove(struct platform_device *dev)
1532{ 1532{
1533 struct wm8400_priv *priv = wm8400_codec->private_data; 1533 struct wm8400_priv *priv = snd_soc_codec_get_drvdata(wm8400_codec);
1534 u16 reg; 1534 u16 reg;
1535 1535
1536 snd_soc_unregister_dai(&wm8400_dai); 1536 snd_soc_unregister_dai(&wm8400_dai);
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 9000b1d19afb..0f7bcb61071a 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -557,7 +557,7 @@ static int wm8510_resume(struct platform_device *pdev)
557 codec->hw_write(codec->control_data, data, 2); 557 codec->hw_write(codec->control_data, data, 2);
558 } 558 }
559 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 559 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
560 wm8510_set_bias_level(codec, codec->suspend_bias_level); 560
561 return 0; 561 return 0;
562} 562}
563 563
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 19cd47293424..37242a7d3077 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -138,7 +138,7 @@ static int wm8523_startup(struct snd_pcm_substream *substream,
138 struct snd_soc_dai *dai) 138 struct snd_soc_dai *dai)
139{ 139{
140 struct snd_soc_codec *codec = dai->codec; 140 struct snd_soc_codec *codec = dai->codec;
141 struct wm8523_priv *wm8523 = codec->private_data; 141 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
142 142
143 /* The set of sample rates that can be supported depends on the 143 /* The set of sample rates that can be supported depends on the
144 * MCLK supplied to the CODEC - enforce this. 144 * MCLK supplied to the CODEC - enforce this.
@@ -164,7 +164,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 164 struct snd_soc_pcm_runtime *rtd = substream->private_data;
165 struct snd_soc_device *socdev = rtd->socdev; 165 struct snd_soc_device *socdev = rtd->socdev;
166 struct snd_soc_codec *codec = socdev->card->codec; 166 struct snd_soc_codec *codec = socdev->card->codec;
167 struct wm8523_priv *wm8523 = codec->private_data; 167 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
168 int i; 168 int i;
169 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1); 169 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
170 u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2); 170 u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);
@@ -211,7 +211,7 @@ static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
211 int clk_id, unsigned int freq, int dir) 211 int clk_id, unsigned int freq, int dir)
212{ 212{
213 struct snd_soc_codec *codec = codec_dai->codec; 213 struct snd_soc_codec *codec = codec_dai->codec;
214 struct wm8523_priv *wm8523 = codec->private_data; 214 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
215 unsigned int val; 215 unsigned int val;
216 int i; 216 int i;
217 217
@@ -318,7 +318,7 @@ static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
318static int wm8523_set_bias_level(struct snd_soc_codec *codec, 318static int wm8523_set_bias_level(struct snd_soc_codec *codec,
319 enum snd_soc_bias_level level) 319 enum snd_soc_bias_level level)
320{ 320{
321 struct wm8523_priv *wm8523 = codec->private_data; 321 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
322 int ret, i; 322 int ret, i;
323 323
324 switch (level) { 324 switch (level) {
@@ -489,7 +489,7 @@ static int wm8523_register(struct wm8523_priv *wm8523,
489 INIT_LIST_HEAD(&codec->dapm_widgets); 489 INIT_LIST_HEAD(&codec->dapm_widgets);
490 INIT_LIST_HEAD(&codec->dapm_paths); 490 INIT_LIST_HEAD(&codec->dapm_paths);
491 491
492 codec->private_data = wm8523; 492 snd_soc_codec_set_drvdata(codec, wm8523);
493 codec->name = "WM8523"; 493 codec->name = "WM8523";
494 codec->owner = THIS_MODULE; 494 codec->owner = THIS_MODULE;
495 codec->bias_level = SND_SOC_BIAS_OFF; 495 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 8cc9042965eb..c3571ee5c11b 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -412,7 +412,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
412{ 412{
413 int offset; 413 int offset;
414 struct snd_soc_codec *codec = codec_dai->codec; 414 struct snd_soc_codec *codec = codec_dai->codec;
415 struct wm8580_priv *wm8580 = codec->private_data; 415 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
416 struct pll_state *state; 416 struct pll_state *state;
417 struct _pll_div pll_div; 417 struct _pll_div pll_div;
418 unsigned int reg; 418 unsigned int reg;
@@ -840,7 +840,7 @@ static int wm8580_register(struct wm8580_priv *wm8580,
840 INIT_LIST_HEAD(&codec->dapm_widgets); 840 INIT_LIST_HEAD(&codec->dapm_widgets);
841 INIT_LIST_HEAD(&codec->dapm_paths); 841 INIT_LIST_HEAD(&codec->dapm_paths);
842 842
843 codec->private_data = wm8580; 843 snd_soc_codec_set_drvdata(codec, wm8580);
844 codec->name = "WM8580"; 844 codec->name = "WM8580";
845 codec->owner = THIS_MODULE; 845 codec->owner = THIS_MODULE;
846 codec->bias_level = SND_SOC_BIAS_OFF; 846 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 8ca3812f2f2f..effb14eee7d4 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -163,7 +163,7 @@ static int wm8711_hw_params(struct snd_pcm_substream *substream,
163 struct snd_soc_dai *dai) 163 struct snd_soc_dai *dai)
164{ 164{
165 struct snd_soc_codec *codec = dai->codec; 165 struct snd_soc_codec *codec = dai->codec;
166 struct wm8711_priv *wm8711 = codec->private_data; 166 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc; 167 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
168 int i = get_coeff(wm8711->sysclk, params_rate(params)); 168 int i = get_coeff(wm8711->sysclk, params_rate(params));
169 u16 srate = (coeff_div[i].sr << 2) | 169 u16 srate = (coeff_div[i].sr << 2) |
@@ -227,7 +227,7 @@ static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
227 int clk_id, unsigned int freq, int dir) 227 int clk_id, unsigned int freq, int dir)
228{ 228{
229 struct snd_soc_codec *codec = codec_dai->codec; 229 struct snd_soc_codec *codec = codec_dai->codec;
230 struct wm8711_priv *wm8711 = codec->private_data; 230 struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
231 231
232 switch (freq) { 232 switch (freq) {
233 case 11289600: 233 case 11289600:
@@ -376,7 +376,7 @@ static int wm8711_resume(struct platform_device *pdev)
376 codec->hw_write(codec->control_data, data, 2); 376 codec->hw_write(codec->control_data, data, 2);
377 } 377 }
378 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 378 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
379 wm8711_set_bias_level(codec, codec->suspend_bias_level); 379
380 return 0; 380 return 0;
381} 381}
382 382
@@ -446,7 +446,7 @@ static int wm8711_register(struct wm8711_priv *wm8711,
446 INIT_LIST_HEAD(&codec->dapm_widgets); 446 INIT_LIST_HEAD(&codec->dapm_widgets);
447 INIT_LIST_HEAD(&codec->dapm_paths); 447 INIT_LIST_HEAD(&codec->dapm_paths);
448 448
449 codec->private_data = wm8711; 449 snd_soc_codec_set_drvdata(codec, wm8711);
450 codec->name = "WM8711"; 450 codec->name = "WM8711";
451 codec->owner = THIS_MODULE; 451 codec->owner = THIS_MODULE;
452 codec->bias_level = SND_SOC_BIAS_OFF; 452 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 07adc375a706..34be2d2b69ef 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -238,7 +238,7 @@ static int wm8728_resume(struct platform_device *pdev)
238 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 238 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
239 struct snd_soc_codec *codec = socdev->card->codec; 239 struct snd_soc_codec *codec = socdev->card->codec;
240 240
241 wm8728_set_bias_level(codec, codec->suspend_bias_level); 241 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
242 242
243 return 0; 243 return 0;
244} 244}
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index e7c6bf163185..0ab9b6355297 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -225,7 +225,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 225 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct snd_soc_device *socdev = rtd->socdev; 226 struct snd_soc_device *socdev = rtd->socdev;
227 struct snd_soc_codec *codec = socdev->card->codec; 227 struct snd_soc_codec *codec = socdev->card->codec;
228 struct wm8731_priv *wm8731 = codec->private_data; 228 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 229 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
230 int i = get_coeff(wm8731->sysclk, params_rate(params)); 230 int i = get_coeff(wm8731->sysclk, params_rate(params));
231 u16 srate = (coeff_div[i].sr << 2) | 231 u16 srate = (coeff_div[i].sr << 2) |
@@ -292,7 +292,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
292 int clk_id, unsigned int freq, int dir) 292 int clk_id, unsigned int freq, int dir)
293{ 293{
294 struct snd_soc_codec *codec = codec_dai->codec; 294 struct snd_soc_codec *codec = codec_dai->codec;
295 struct wm8731_priv *wm8731 = codec->private_data; 295 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
296 296
297 switch (freq) { 297 switch (freq) {
298 case 11289600: 298 case 11289600:
@@ -369,6 +369,10 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
369static int wm8731_set_bias_level(struct snd_soc_codec *codec, 369static int wm8731_set_bias_level(struct snd_soc_codec *codec,
370 enum snd_soc_bias_level level) 370 enum snd_soc_bias_level level)
371{ 371{
372 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
373 int i, ret;
374 u8 data[2];
375 u16 *cache = codec->reg_cache;
372 u16 reg; 376 u16 reg;
373 377
374 switch (level) { 378 switch (level) {
@@ -377,6 +381,24 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
377 case SND_SOC_BIAS_PREPARE: 381 case SND_SOC_BIAS_PREPARE:
378 break; 382 break;
379 case SND_SOC_BIAS_STANDBY: 383 case SND_SOC_BIAS_STANDBY:
384 if (codec->bias_level == SND_SOC_BIAS_OFF) {
385 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
386 wm8731->supplies);
387 if (ret != 0)
388 return ret;
389
390 /* Sync reg_cache with the hardware */
391 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
392 if (cache[i] == wm8731_reg[i])
393 continue;
394
395 data[0] = (i << 1) | ((cache[i] >> 8)
396 & 0x0001);
397 data[1] = cache[i] & 0x00ff;
398 codec->hw_write(codec->control_data, data, 2);
399 }
400 }
401
380 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 402 /* Clear PWROFF, gate CLKOUT, everything else as-is */
381 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f; 403 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
382 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); 404 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
@@ -384,17 +406,15 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
384 case SND_SOC_BIAS_OFF: 406 case SND_SOC_BIAS_OFF:
385 snd_soc_write(codec, WM8731_ACTIVE, 0x0); 407 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
386 snd_soc_write(codec, WM8731_PWR, 0xffff); 408 snd_soc_write(codec, WM8731_PWR, 0xffff);
409 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
410 wm8731->supplies);
387 break; 411 break;
388 } 412 }
389 codec->bias_level = level; 413 codec->bias_level = level;
390 return 0; 414 return 0;
391} 415}
392 416
393#define WM8731_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 417#define WM8731_RATES SNDRV_PCM_RATE_8000_96000
394 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
395 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
396 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
397 SNDRV_PCM_RATE_96000)
398 418
399#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 419#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
400 SNDRV_PCM_FMTBIT_S24_LE) 420 SNDRV_PCM_FMTBIT_S24_LE)
@@ -432,12 +452,9 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
432{ 452{
433 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 453 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
434 struct snd_soc_codec *codec = socdev->card->codec; 454 struct snd_soc_codec *codec = socdev->card->codec;
435 struct wm8731_priv *wm8731 = codec->private_data;
436 455
437 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
438 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 456 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
439 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 457
440 wm8731->supplies);
441 return 0; 458 return 0;
442} 459}
443 460
@@ -445,27 +462,8 @@ static int wm8731_resume(struct platform_device *pdev)
445{ 462{
446 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
447 struct snd_soc_codec *codec = socdev->card->codec; 464 struct snd_soc_codec *codec = socdev->card->codec;
448 struct wm8731_priv *wm8731 = codec->private_data;
449 int i, ret;
450 u8 data[2];
451 u16 *cache = codec->reg_cache;
452 465
453 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
454 wm8731->supplies);
455 if (ret != 0)
456 return ret;
457
458 /* Sync reg_cache with the hardware */
459 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
460 if (cache[i] == wm8731_reg[i])
461 continue;
462
463 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
464 data[1] = cache[i] & 0x00ff;
465 codec->hw_write(codec->control_data, data, 2);
466 }
467 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 466 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
468 wm8731_set_bias_level(codec, codec->suspend_bias_level);
469 467
470 return 0; 468 return 0;
471} 469}
@@ -540,7 +538,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
540 INIT_LIST_HEAD(&codec->dapm_widgets); 538 INIT_LIST_HEAD(&codec->dapm_widgets);
541 INIT_LIST_HEAD(&codec->dapm_paths); 539 INIT_LIST_HEAD(&codec->dapm_paths);
542 540
543 codec->private_data = wm8731; 541 snd_soc_codec_set_drvdata(codec, wm8731);
544 codec->name = "WM8731"; 542 codec->name = "WM8731";
545 codec->owner = THIS_MODULE; 543 codec->owner = THIS_MODULE;
546 codec->bias_level = SND_SOC_BIAS_OFF; 544 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -609,6 +607,9 @@ static int wm8731_register(struct wm8731_priv *wm8731,
609 goto err_codec; 607 goto err_codec;
610 } 608 }
611 609
610 /* Regulators will have been enabled by bias management */
611 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
612
612 return 0; 613 return 0;
613 614
614err_codec: 615err_codec:
@@ -627,7 +628,6 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
627 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 628 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
628 snd_soc_unregister_dai(&wm8731_dai); 629 snd_soc_unregister_dai(&wm8731_dai);
629 snd_soc_unregister_codec(&wm8731->codec); 630 snd_soc_unregister_codec(&wm8731->codec);
630 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 631 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
632 kfree(wm8731); 632 kfree(wm8731);
633 wm8731_codec = NULL; 633 wm8731_codec = NULL;
@@ -708,7 +708,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
708 708
709static struct i2c_driver wm8731_i2c_driver = { 709static struct i2c_driver wm8731_i2c_driver = {
710 .driver = { 710 .driver = {
711 .name = "WM8731 I2C Codec", 711 .name = "wm8731",
712 .owner = THIS_MODULE, 712 .owner = THIS_MODULE,
713 }, 713 },
714 .probe = wm8731_i2c_probe, 714 .probe = wm8731_i2c_probe,
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 2916ed4d3844..9407e193fcc3 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -30,13 +30,6 @@
30 30
31#include "wm8750.h" 31#include "wm8750.h"
32 32
33#define WM8750_VERSION "0.12"
34
35/* codec private data */
36struct wm8750_priv {
37 unsigned int sysclk;
38};
39
40/* 33/*
41 * wm8750 register cache 34 * wm8750 register cache
42 * We can't read the WM8750 register space when we 35 * We can't read the WM8750 register space when we
@@ -56,6 +49,13 @@ static const u16 wm8750_reg[] = {
56 0x0079, 0x0079, 0x0079, /* 40 */ 49 0x0079, 0x0079, 0x0079, /* 40 */
57}; 50};
58 51
52/* codec private data */
53struct wm8750_priv {
54 unsigned int sysclk;
55 struct snd_soc_codec codec;
56 u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
57};
58
59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) 59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
60 60
61/* 61/*
@@ -483,7 +483,7 @@ static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
483 int clk_id, unsigned int freq, int dir) 483 int clk_id, unsigned int freq, int dir)
484{ 484{
485 struct snd_soc_codec *codec = codec_dai->codec; 485 struct snd_soc_codec *codec = codec_dai->codec;
486 struct wm8750_priv *wm8750 = codec->private_data; 486 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
487 487
488 switch (freq) { 488 switch (freq) {
489 case 11289600: 489 case 11289600:
@@ -562,7 +562,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
562 struct snd_soc_pcm_runtime *rtd = substream->private_data; 562 struct snd_soc_pcm_runtime *rtd = substream->private_data;
563 struct snd_soc_device *socdev = rtd->socdev; 563 struct snd_soc_device *socdev = rtd->socdev;
564 struct snd_soc_codec *codec = socdev->card->codec; 564 struct snd_soc_codec *codec = socdev->card->codec;
565 struct wm8750_priv *wm8750 = codec->private_data; 565 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; 566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; 567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
568 int coeff = get_coeff(wm8750->sysclk, params_rate(params)); 568 int coeff = get_coeff(wm8750->sysclk, params_rate(params));
@@ -614,10 +614,16 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
615 break; 615 break;
616 case SND_SOC_BIAS_PREPARE: 616 case SND_SOC_BIAS_PREPARE:
617 /* set vmid to 5k for quick power up */
618 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
619 break; 617 break;
620 case SND_SOC_BIAS_STANDBY: 618 case SND_SOC_BIAS_STANDBY:
619 if (codec->bias_level == SND_SOC_BIAS_OFF) {
620 /* Set VMID to 5k */
621 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
622
623 /* ...and ramp */
624 msleep(1000);
625 }
626
621 /* mute dac and set vmid to 500k, enable VREF */ 627 /* mute dac and set vmid to 500k, enable VREF */
622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 628 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
623 break; 629 break;
@@ -661,13 +667,6 @@ struct snd_soc_dai wm8750_dai = {
661}; 667};
662EXPORT_SYMBOL_GPL(wm8750_dai); 668EXPORT_SYMBOL_GPL(wm8750_dai);
663 669
664static void wm8750_work(struct work_struct *work)
665{
666 struct snd_soc_codec *codec =
667 container_of(work, struct snd_soc_codec, delayed_work.work);
668 wm8750_set_bias_level(codec, codec->bias_level);
669}
670
671static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 670static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
672{ 671{
673 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 672 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -696,36 +695,92 @@ static int wm8750_resume(struct platform_device *pdev)
696 695
697 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 696 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
698 697
699 /* charge wm8750 caps */ 698 return 0;
700 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 699}
701 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 700
702 codec->bias_level = SND_SOC_BIAS_ON; 701static struct snd_soc_codec *wm8750_codec;
703 schedule_delayed_work(&codec->delayed_work, 702
704 msecs_to_jiffies(1000)); 703static int wm8750_probe(struct platform_device *pdev)
704{
705 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
706 struct snd_soc_codec *codec;
707 int ret = 0;
708
709 if (!wm8750_codec) {
710 dev_err(&pdev->dev, "WM8750 codec not yet registered\n");
711 return -EINVAL;
712 }
713
714 socdev->card->codec = wm8750_codec;
715 codec = wm8750_codec;
716
717 /* register pcms */
718 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
719 if (ret < 0) {
720 printk(KERN_ERR "wm8750: failed to create pcms\n");
721 goto err;
705 } 722 }
706 723
724 snd_soc_add_controls(codec, wm8750_snd_controls,
725 ARRAY_SIZE(wm8750_snd_controls));
726 wm8750_add_widgets(codec);
727
728 return 0;
729
730err:
731 return ret;
732}
733
734/* power down chip */
735static int wm8750_remove(struct platform_device *pdev)
736{
737 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
738
739 snd_soc_free_pcms(socdev);
740 snd_soc_dapm_free(socdev);
741
707 return 0; 742 return 0;
708} 743}
709 744
745struct snd_soc_codec_device soc_codec_dev_wm8750 = {
746 .probe = wm8750_probe,
747 .remove = wm8750_remove,
748 .suspend = wm8750_suspend,
749 .resume = wm8750_resume,
750};
751EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
752
710/* 753/*
711 * initialise the WM8750 driver 754 * initialise the WM8750 driver
712 * register the mixer and dsp interfaces with the kernel 755 * register the mixer and dsp interfaces with the kernel
713 */ 756 */
714static int wm8750_init(struct snd_soc_device *socdev, 757static int wm8750_register(struct wm8750_priv *wm8750,
715 enum snd_soc_control_type control) 758 enum snd_soc_control_type control)
716{ 759{
717 struct snd_soc_codec *codec = socdev->card->codec; 760 struct snd_soc_codec *codec = &wm8750->codec;
718 int reg, ret = 0; 761 int reg, ret = 0;
719 762
763 if (wm8750_codec) {
764 dev_err(codec->dev, "Multiple WM8750 devices not supported\n");
765 ret = -EINVAL;
766 goto err;
767 }
768
769 mutex_init(&codec->mutex);
770 INIT_LIST_HEAD(&codec->dapm_widgets);
771 INIT_LIST_HEAD(&codec->dapm_paths);
772
720 codec->name = "WM8750"; 773 codec->name = "WM8750";
721 codec->owner = THIS_MODULE; 774 codec->owner = THIS_MODULE;
775 codec->bias_level = SND_SOC_BIAS_STANDBY;
722 codec->set_bias_level = wm8750_set_bias_level; 776 codec->set_bias_level = wm8750_set_bias_level;
723 codec->dai = &wm8750_dai; 777 codec->dai = &wm8750_dai;
724 codec->num_dai = 1; 778 codec->num_dai = 1;
725 codec->reg_cache_size = ARRAY_SIZE(wm8750_reg); 779 codec->reg_cache_size = ARRAY_SIZE(wm8750->reg_cache) + 1;
726 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); 780 codec->reg_cache = &wm8750->reg_cache;
727 if (codec->reg_cache == NULL) 781 snd_soc_codec_set_drvdata(codec, wm8750);
728 return -ENOMEM; 782
783 memcpy(codec->reg_cache, wm8750_reg, sizeof(wm8750->reg_cache));
729 784
730 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 785 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
731 if (ret < 0) { 786 if (ret < 0) {
@@ -739,17 +794,8 @@ static int wm8750_init(struct snd_soc_device *socdev,
739 goto err; 794 goto err;
740 } 795 }
741 796
742 /* register pcms */
743 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
744 if (ret < 0) {
745 printk(KERN_ERR "wm8750: failed to create pcms\n");
746 goto err;
747 }
748
749 /* charge output caps */ 797 /* charge output caps */
750 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 798 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
751 codec->bias_level = SND_SOC_BIAS_STANDBY;
752 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
753 799
754 /* set the update bits */ 800 /* set the update bits */
755 reg = snd_soc_read(codec, WM8750_LDAC); 801 reg = snd_soc_read(codec, WM8750_LDAC);
@@ -769,19 +815,37 @@ static int wm8750_init(struct snd_soc_device *socdev,
769 reg = snd_soc_read(codec, WM8750_RINVOL); 815 reg = snd_soc_read(codec, WM8750_RINVOL);
770 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); 816 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
771 817
772 snd_soc_add_controls(codec, wm8750_snd_controls, 818 wm8750_codec = codec;
773 ARRAY_SIZE(wm8750_snd_controls));
774 wm8750_add_widgets(codec);
775 return ret;
776 819
820 ret = snd_soc_register_codec(codec);
821 if (ret != 0) {
822 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
823 goto err;
824 }
825
826 ret = snd_soc_register_dais(&wm8750_dai, 1);
827 if (ret != 0) {
828 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
829 goto err_codec;
830 }
831
832 return 0;
833
834err_codec:
835 snd_soc_unregister_codec(codec);
777err: 836err:
778 kfree(codec->reg_cache); 837 kfree(wm8750);
779 return ret; 838 return ret;
780} 839}
781 840
782/* If the i2c layer weren't so broken, we could pass this kind of data 841static void wm8750_unregister(struct wm8750_priv *wm8750)
783 around */ 842{
784static struct snd_soc_device *wm8750_socdev; 843 wm8750_set_bias_level(&wm8750->codec, SND_SOC_BIAS_OFF);
844 snd_soc_unregister_dais(&wm8750_dai, 1);
845 snd_soc_unregister_codec(&wm8750->codec);
846 kfree(wm8750);
847 wm8750_codec = NULL;
848}
785 849
786#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 850#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
787 851
@@ -795,24 +859,26 @@ static struct snd_soc_device *wm8750_socdev;
795static int wm8750_i2c_probe(struct i2c_client *i2c, 859static int wm8750_i2c_probe(struct i2c_client *i2c,
796 const struct i2c_device_id *id) 860 const struct i2c_device_id *id)
797{ 861{
798 struct snd_soc_device *socdev = wm8750_socdev; 862 struct snd_soc_codec *codec;
799 struct snd_soc_codec *codec = socdev->card->codec; 863 struct wm8750_priv *wm8750;
800 int ret; 864
865 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
866 if (wm8750 == NULL)
867 return -ENOMEM;
801 868
802 i2c_set_clientdata(i2c, codec); 869 codec = &wm8750->codec;
803 codec->control_data = i2c; 870 codec->control_data = i2c;
871 i2c_set_clientdata(i2c, wm8750);
804 872
805 ret = wm8750_init(socdev, SND_SOC_I2C); 873 codec->dev = &i2c->dev;
806 if (ret < 0)
807 pr_err("failed to initialise WM8750\n");
808 874
809 return ret; 875 return wm8750_register(wm8750, SND_SOC_I2C);
810} 876}
811 877
812static int wm8750_i2c_remove(struct i2c_client *client) 878static int wm8750_i2c_remove(struct i2c_client *client)
813{ 879{
814 struct snd_soc_codec *codec = i2c_get_clientdata(client); 880 struct wm8750_priv *wm8750 = i2c_get_clientdata(client);
815 kfree(codec->reg_cache); 881 wm8750_unregister(wm8750);
816 return 0; 882 return 0;
817} 883}
818 884
@@ -831,66 +897,31 @@ static struct i2c_driver wm8750_i2c_driver = {
831 .remove = wm8750_i2c_remove, 897 .remove = wm8750_i2c_remove,
832 .id_table = wm8750_i2c_id, 898 .id_table = wm8750_i2c_id,
833}; 899};
834
835static int wm8750_add_i2c_device(struct platform_device *pdev,
836 const struct wm8750_setup_data *setup)
837{
838 struct i2c_board_info info;
839 struct i2c_adapter *adapter;
840 struct i2c_client *client;
841 int ret;
842
843 ret = i2c_add_driver(&wm8750_i2c_driver);
844 if (ret != 0) {
845 dev_err(&pdev->dev, "can't add i2c driver\n");
846 return ret;
847 }
848
849 memset(&info, 0, sizeof(struct i2c_board_info));
850 info.addr = setup->i2c_address;
851 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
852
853 adapter = i2c_get_adapter(setup->i2c_bus);
854 if (!adapter) {
855 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
856 setup->i2c_bus);
857 goto err_driver;
858 }
859
860 client = i2c_new_device(adapter, &info);
861 i2c_put_adapter(adapter);
862 if (!client) {
863 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
864 (unsigned int)info.addr);
865 goto err_driver;
866 }
867
868 return 0;
869
870err_driver:
871 i2c_del_driver(&wm8750_i2c_driver);
872 return -ENODEV;
873}
874#endif 900#endif
875 901
876#if defined(CONFIG_SPI_MASTER) 902#if defined(CONFIG_SPI_MASTER)
877static int __devinit wm8750_spi_probe(struct spi_device *spi) 903static int __devinit wm8750_spi_probe(struct spi_device *spi)
878{ 904{
879 struct snd_soc_device *socdev = wm8750_socdev; 905 struct snd_soc_codec *codec;
880 struct snd_soc_codec *codec = socdev->card->codec; 906 struct wm8750_priv *wm8750;
881 int ret; 907
908 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
909 if (wm8750 == NULL)
910 return -ENOMEM;
882 911
912 codec = &wm8750->codec;
883 codec->control_data = spi; 913 codec->control_data = spi;
914 codec->dev = &spi->dev;
884 915
885 ret = wm8750_init(socdev, SND_SOC_SPI); 916 dev_set_drvdata(&spi->dev, wm8750);
886 if (ret < 0)
887 dev_err(&spi->dev, "failed to initialise WM8750\n");
888 917
889 return ret; 918 return wm8750_register(wm8750, SND_SOC_SPI);
890} 919}
891 920
892static int __devexit wm8750_spi_remove(struct spi_device *spi) 921static int __devexit wm8750_spi_remove(struct spi_device *spi)
893{ 922{
923 struct wm8750_priv *wm8750 = dev_get_drvdata(&spi->dev);
924 wm8750_unregister(wm8750);
894 return 0; 925 return 0;
895} 926}
896 927
@@ -905,115 +936,31 @@ static struct spi_driver wm8750_spi_driver = {
905}; 936};
906#endif 937#endif
907 938
908static int wm8750_probe(struct platform_device *pdev) 939static int __init wm8750_modinit(void)
909{ 940{
910 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
911 struct wm8750_setup_data *setup = socdev->codec_data;
912 struct snd_soc_codec *codec;
913 struct wm8750_priv *wm8750;
914 int ret; 941 int ret;
915
916 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
917 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
918 if (codec == NULL)
919 return -ENOMEM;
920
921 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
922 if (wm8750 == NULL) {
923 kfree(codec);
924 return -ENOMEM;
925 }
926
927 codec->private_data = wm8750;
928 socdev->card->codec = codec;
929 mutex_init(&codec->mutex);
930 INIT_LIST_HEAD(&codec->dapm_widgets);
931 INIT_LIST_HEAD(&codec->dapm_paths);
932 wm8750_socdev = socdev;
933 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work);
934
935 ret = -ENODEV;
936
937#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 942#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
938 if (setup->i2c_address) { 943 ret = i2c_add_driver(&wm8750_i2c_driver);
939 ret = wm8750_add_i2c_device(pdev, setup); 944 if (ret != 0)
940 } 945 pr_err("Failed to register WM8750 I2C driver: %d\n", ret);
941#endif 946#endif
942#if defined(CONFIG_SPI_MASTER) 947#if defined(CONFIG_SPI_MASTER)
943 if (setup->spi) { 948 ret = spi_register_driver(&wm8750_spi_driver);
944 ret = spi_register_driver(&wm8750_spi_driver); 949 if (ret != 0)
945 if (ret != 0) 950 pr_err("Failed to register WM8750 SPI driver: %d\n", ret);
946 printk(KERN_ERR "can't add spi driver");
947 }
948#endif 951#endif
949 952 return 0;
950 if (ret != 0) {
951 kfree(codec->private_data);
952 kfree(codec);
953 }
954 return ret;
955}
956
957/*
958 * This function forces any delayed work to be queued and run.
959 */
960static int run_delayed_work(struct delayed_work *dwork)
961{
962 int ret;
963
964 /* cancel any work waiting to be queued. */
965 ret = cancel_delayed_work(dwork);
966
967 /* if there was any work waiting then we run it now and
968 * wait for it's completion */
969 if (ret) {
970 schedule_delayed_work(dwork, 0);
971 flush_scheduled_work();
972 }
973 return ret;
974} 953}
954module_init(wm8750_modinit);
975 955
976/* power down chip */ 956static void __exit wm8750_exit(void)
977static int wm8750_remove(struct platform_device *pdev)
978{ 957{
979 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
980 struct snd_soc_codec *codec = socdev->card->codec;
981
982 if (codec->control_data)
983 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
984 run_delayed_work(&codec->delayed_work);
985 snd_soc_free_pcms(socdev);
986 snd_soc_dapm_free(socdev);
987#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 958#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
988 i2c_unregister_device(codec->control_data);
989 i2c_del_driver(&wm8750_i2c_driver); 959 i2c_del_driver(&wm8750_i2c_driver);
990#endif 960#endif
991#if defined(CONFIG_SPI_MASTER) 961#if defined(CONFIG_SPI_MASTER)
992 spi_unregister_driver(&wm8750_spi_driver); 962 spi_unregister_driver(&wm8750_spi_driver);
993#endif 963#endif
994 kfree(codec->private_data);
995 kfree(codec);
996
997 return 0;
998}
999
1000struct snd_soc_codec_device soc_codec_dev_wm8750 = {
1001 .probe = wm8750_probe,
1002 .remove = wm8750_remove,
1003 .suspend = wm8750_suspend,
1004 .resume = wm8750_resume,
1005};
1006EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
1007
1008static int __init wm8750_modinit(void)
1009{
1010 return snd_soc_register_dai(&wm8750_dai);
1011}
1012module_init(wm8750_modinit);
1013
1014static void __exit wm8750_exit(void)
1015{
1016 snd_soc_unregister_dai(&wm8750_dai);
1017} 964}
1018module_exit(wm8750_exit); 965module_exit(wm8750_exit);
1019 966
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 613199a0f799..b59f349c5218 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -851,7 +851,7 @@ static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
851 int clk_id, unsigned int freq, int dir) 851 int clk_id, unsigned int freq, int dir)
852{ 852{
853 struct snd_soc_codec *codec = codec_dai->codec; 853 struct snd_soc_codec *codec = codec_dai->codec;
854 struct wm8753_priv *wm8753 = codec->private_data; 854 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
855 855
856 switch (freq) { 856 switch (freq) {
857 case 11289600: 857 case 11289600:
@@ -914,7 +914,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
914 struct snd_soc_pcm_runtime *rtd = substream->private_data; 914 struct snd_soc_pcm_runtime *rtd = substream->private_data;
915 struct snd_soc_device *socdev = rtd->socdev; 915 struct snd_soc_device *socdev = rtd->socdev;
916 struct snd_soc_codec *codec = socdev->card->codec; 916 struct snd_soc_codec *codec = socdev->card->codec;
917 struct wm8753_priv *wm8753 = codec->private_data; 917 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
918 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; 918 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
919 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; 919 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
920 920
@@ -1148,7 +1148,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1148 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1149 struct snd_soc_device *socdev = rtd->socdev; 1149 struct snd_soc_device *socdev = rtd->socdev;
1150 struct snd_soc_codec *codec = socdev->card->codec; 1150 struct snd_soc_codec *codec = socdev->card->codec;
1151 struct wm8753_priv *wm8753 = codec->private_data; 1151 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1152 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; 1152 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
1153 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; 1153 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
1154 int coeff; 1154 int coeff;
@@ -1646,7 +1646,7 @@ static int wm8753_register(struct wm8753_priv *wm8753)
1646 codec->num_dai = 2; 1646 codec->num_dai = 2;
1647 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1; 1647 codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1;
1648 codec->reg_cache = &wm8753->reg_cache; 1648 codec->reg_cache = &wm8753->reg_cache;
1649 codec->private_data = wm8753; 1649 snd_soc_codec_set_drvdata(codec, wm8753);
1650 1650
1651 memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache)); 1651 memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
1652 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); 1652 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 60b1b3e1094b..7e4a627b4c7e 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -227,7 +227,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream,
227 struct snd_soc_dai *dai) 227 struct snd_soc_dai *dai)
228{ 228{
229 struct snd_soc_codec *codec = dai->codec; 229 struct snd_soc_codec *codec = dai->codec;
230 struct wm8776_priv *wm8776 = codec->private_data; 230 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
231 int iface_reg, iface; 231 int iface_reg, iface;
232 int ratio_shift, master; 232 int ratio_shift, master;
233 int i; 233 int i;
@@ -304,7 +304,7 @@ static int wm8776_set_sysclk(struct snd_soc_dai *dai,
304 int clk_id, unsigned int freq, int dir) 304 int clk_id, unsigned int freq, int dir)
305{ 305{
306 struct snd_soc_codec *codec = dai->codec; 306 struct snd_soc_codec *codec = dai->codec;
307 struct wm8776_priv *wm8776 = codec->private_data; 307 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
308 308
309 BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk)); 309 BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk));
310 310
@@ -491,7 +491,7 @@ static int wm8776_register(struct wm8776_priv *wm8776,
491 INIT_LIST_HEAD(&codec->dapm_widgets); 491 INIT_LIST_HEAD(&codec->dapm_widgets);
492 INIT_LIST_HEAD(&codec->dapm_paths); 492 INIT_LIST_HEAD(&codec->dapm_paths);
493 493
494 codec->private_data = wm8776; 494 snd_soc_codec_set_drvdata(codec, wm8776);
495 codec->name = "WM8776"; 495 codec->name = "WM8776";
496 codec->owner = THIS_MODULE; 496 codec->owner = THIS_MODULE;
497 codec->bias_level = SND_SOC_BIAS_OFF; 497 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index b7fd96adac64..5da17a704e5a 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -745,7 +745,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
745static int wm8900_set_fll(struct snd_soc_codec *codec, 745static int wm8900_set_fll(struct snd_soc_codec *codec,
746 int fll_id, unsigned int freq_in, unsigned int freq_out) 746 int fll_id, unsigned int freq_in, unsigned int freq_out)
747{ 747{
748 struct wm8900_priv *wm8900 = codec->private_data; 748 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
749 struct _fll_div fll_div; 749 struct _fll_div fll_div;
750 unsigned int reg; 750 unsigned int reg;
751 751
@@ -1132,7 +1132,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1132{ 1132{
1133 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1133 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1134 struct snd_soc_codec *codec = socdev->card->codec; 1134 struct snd_soc_codec *codec = socdev->card->codec;
1135 struct wm8900_priv *wm8900 = codec->private_data; 1135 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1136 int fll_out = wm8900->fll_out; 1136 int fll_out = wm8900->fll_out;
1137 int fll_in = wm8900->fll_in; 1137 int fll_in = wm8900->fll_in;
1138 int ret; 1138 int ret;
@@ -1156,7 +1156,7 @@ static int wm8900_resume(struct platform_device *pdev)
1156{ 1156{
1157 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1157 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1158 struct snd_soc_codec *codec = socdev->card->codec; 1158 struct snd_soc_codec *codec = socdev->card->codec;
1159 struct wm8900_priv *wm8900 = codec->private_data; 1159 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1160 u16 *cache; 1160 u16 *cache;
1161 int i, ret; 1161 int i, ret;
1162 1162
@@ -1206,7 +1206,7 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1206 return -ENOMEM; 1206 return -ENOMEM;
1207 1207
1208 codec = &wm8900->codec; 1208 codec = &wm8900->codec;
1209 codec->private_data = wm8900; 1209 snd_soc_codec_set_drvdata(codec, wm8900);
1210 codec->reg_cache = &wm8900->reg_cache[0]; 1210 codec->reg_cache = &wm8900->reg_cache[0];
1211 codec->reg_cache_size = WM8900_MAXREG; 1211 codec->reg_cache_size = WM8900_MAXREG;
1212 1212
@@ -1305,7 +1305,7 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1305 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF); 1305 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
1306 1306
1307 wm8900_dai.dev = NULL; 1307 wm8900_dai.dev = NULL;
1308 kfree(wm8900_codec->private_data); 1308 kfree(snd_soc_codec_get_drvdata(wm8900_codec));
1309 wm8900_codec = NULL; 1309 wm8900_codec = NULL;
1310 1310
1311 return 0; 1311 return 0;
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fa5f99fde68b..bf08282d5ee5 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -11,26 +11,27 @@
11 * 11 *
12 * TODO: 12 * TODO:
13 * - TDM mode configuration. 13 * - TDM mode configuration.
14 * - Mic detect.
15 * - Digital microphone support. 14 * - Digital microphone support.
16 * - Interrupt support (mic detect and sequencer).
17 */ 15 */
18 16
19#include <linux/module.h> 17#include <linux/module.h>
20#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
21#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/completion.h>
22#include <linux/delay.h> 21#include <linux/delay.h>
23#include <linux/pm.h> 22#include <linux/pm.h>
24#include <linux/i2c.h> 23#include <linux/i2c.h>
25#include <linux/platform_device.h> 24#include <linux/platform_device.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/jack.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h> 32#include <sound/soc-dapm.h>
33#include <sound/initval.h> 33#include <sound/initval.h>
34#include <sound/wm8903.h>
34 35
35#include "wm8903.h" 36#include "wm8903.h"
36 37
@@ -222,6 +223,14 @@ struct wm8903_priv {
222 int playback_active; 223 int playback_active;
223 int capture_active; 224 int capture_active;
224 225
226 struct completion wseq;
227
228 struct snd_soc_jack *mic_jack;
229 int mic_det;
230 int mic_short;
231 int mic_last_report;
232 int mic_delay;
233
225 struct snd_pcm_substream *master_substream; 234 struct snd_pcm_substream *master_substream;
226 struct snd_pcm_substream *slave_substream; 235 struct snd_pcm_substream *slave_substream;
227}; 236};
@@ -244,13 +253,14 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
244{ 253{
245 u16 reg[5]; 254 u16 reg[5];
246 struct i2c_client *i2c = codec->control_data; 255 struct i2c_client *i2c = codec->control_data;
256 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
247 257
248 BUG_ON(start > 48); 258 BUG_ON(start > 48);
249 259
250 /* Enable the sequencer */ 260 /* Enable the sequencer if it's not already on */
251 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0); 261 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
252 reg[0] |= WM8903_WSEQ_ENA; 262 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
253 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); 263 reg[0] | WM8903_WSEQ_ENA);
254 264
255 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start); 265 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
256 266
@@ -258,20 +268,19 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
258 start | WM8903_WSEQ_START); 268 start | WM8903_WSEQ_START);
259 269
260 /* Wait for it to complete. If we have the interrupt wired up then 270 /* Wait for it to complete. If we have the interrupt wired up then
261 * we could block waiting for an interrupt, though polling may still 271 * that will break us out of the poll early.
262 * be desirable for diagnostic purposes.
263 */ 272 */
264 do { 273 do {
265 msleep(10); 274 wait_for_completion_timeout(&wm8903->wseq,
275 msecs_to_jiffies(10));
266 276
267 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4); 277 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
268 } while (reg[4] & WM8903_WSEQ_BUSY); 278 } while (reg[4] & WM8903_WSEQ_BUSY);
269 279
270 dev_dbg(&i2c->dev, "Sequence complete\n"); 280 dev_dbg(&i2c->dev, "Sequence complete\n");
271 281
272 /* Disable the sequencer again */ 282 /* Disable the sequencer again if we enabled it */
273 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 283 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
274 reg[0] & ~WM8903_WSEQ_ENA);
275 284
276 return 0; 285 return 0;
277} 286}
@@ -412,7 +421,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
412{ 421{
413 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 422 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
414 struct snd_soc_codec *codec = widget->codec; 423 struct snd_soc_codec *codec = widget->codec;
415 struct wm8903_priv *wm8903 = codec->private_data; 424 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
416 struct i2c_client *i2c = codec->control_data; 425 struct i2c_client *i2c = codec->control_data;
417 u16 reg; 426 u16 reg;
418 int ret; 427 int ret;
@@ -993,7 +1002,7 @@ static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai,
993 int clk_id, unsigned int freq, int dir) 1002 int clk_id, unsigned int freq, int dir)
994{ 1003{
995 struct snd_soc_codec *codec = codec_dai->codec; 1004 struct snd_soc_codec *codec = codec_dai->codec;
996 struct wm8903_priv *wm8903 = codec->private_data; 1005 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
997 1006
998 wm8903->sysclk = freq; 1007 wm8903->sysclk = freq;
999 1008
@@ -1221,7 +1230,7 @@ static int wm8903_startup(struct snd_pcm_substream *substream,
1221 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1230 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1222 struct snd_soc_device *socdev = rtd->socdev; 1231 struct snd_soc_device *socdev = rtd->socdev;
1223 struct snd_soc_codec *codec = socdev->card->codec; 1232 struct snd_soc_codec *codec = socdev->card->codec;
1224 struct wm8903_priv *wm8903 = codec->private_data; 1233 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1225 struct i2c_client *i2c = codec->control_data; 1234 struct i2c_client *i2c = codec->control_data;
1226 struct snd_pcm_runtime *master_runtime; 1235 struct snd_pcm_runtime *master_runtime;
1227 1236
@@ -1257,7 +1266,7 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream,
1257 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1266 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1258 struct snd_soc_device *socdev = rtd->socdev; 1267 struct snd_soc_device *socdev = rtd->socdev;
1259 struct snd_soc_codec *codec = socdev->card->codec; 1268 struct snd_soc_codec *codec = socdev->card->codec;
1260 struct wm8903_priv *wm8903 = codec->private_data; 1269 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1261 1270
1262 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1271 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1263 wm8903->playback_active--; 1272 wm8903->playback_active--;
@@ -1277,7 +1286,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1286 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1278 struct snd_soc_device *socdev = rtd->socdev; 1287 struct snd_soc_device *socdev = rtd->socdev;
1279 struct snd_soc_codec *codec = socdev->card->codec; 1288 struct snd_soc_codec *codec = socdev->card->codec;
1280 struct wm8903_priv *wm8903 = codec->private_data; 1289 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1281 struct i2c_client *i2c = codec->control_data; 1290 struct i2c_client *i2c = codec->control_data;
1282 int fs = params_rate(params); 1291 int fs = params_rate(params);
1283 int bclk; 1292 int bclk;
@@ -1436,6 +1445,116 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1436 return 0; 1445 return 0;
1437} 1446}
1438 1447
1448/**
1449 * wm8903_mic_detect - Enable microphone detection via the WM8903 IRQ
1450 *
1451 * @codec: WM8903 codec
1452 * @jack: jack to report detection events on
1453 * @det: value to report for presence detection
1454 * @shrt: value to report for short detection
1455 *
1456 * Enable microphone detection via IRQ on the WM8903. If GPIOs are
1457 * being used to bring out signals to the processor then only platform
1458 * data configuration is needed for WM8903 and processor GPIOs should
1459 * be configured using snd_soc_jack_add_gpios() instead.
1460 *
1461 * The current threasholds for detection should be configured using
1462 * micdet_cfg in the platform data. Using this function will force on
1463 * the microphone bias for the device.
1464 */
1465int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
1466 int det, int shrt)
1467{
1468 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1469 int irq_mask = WM8903_MICDET_EINT | WM8903_MICSHRT_EINT;
1470
1471 dev_dbg(codec->dev, "Enabling microphone detection: %x %x\n",
1472 det, shrt);
1473
1474 /* Store the configuration */
1475 wm8903->mic_jack = jack;
1476 wm8903->mic_det = det;
1477 wm8903->mic_short = shrt;
1478
1479 /* Enable interrupts we've got a report configured for */
1480 if (det)
1481 irq_mask &= ~WM8903_MICDET_EINT;
1482 if (shrt)
1483 irq_mask &= ~WM8903_MICSHRT_EINT;
1484
1485 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
1486 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT,
1487 irq_mask);
1488
1489 if (det && shrt) {
1490 /* Enable mic detection, this may not have been set through
1491 * platform data (eg, if the defaults are OK). */
1492 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1493 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1494 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
1495 WM8903_MICDET_ENA, WM8903_MICDET_ENA);
1496 } else {
1497 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0,
1498 WM8903_MICDET_ENA, 0);
1499 }
1500
1501 return 0;
1502}
1503EXPORT_SYMBOL_GPL(wm8903_mic_detect);
1504
1505static irqreturn_t wm8903_irq(int irq, void *data)
1506{
1507 struct wm8903_priv *wm8903 = data;
1508 struct snd_soc_codec *codec = &wm8903->codec;
1509 int mic_report;
1510 int int_pol;
1511 int int_val = 0;
1512 int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK);
1513
1514 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask;
1515
1516 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1517 dev_dbg(codec->dev, "Write sequencer done\n");
1518 complete(&wm8903->wseq);
1519 }
1520
1521 /*
1522 * The rest is microphone jack detection. We need to manually
1523 * invert the polarity of the interrupt after each event - to
1524 * simplify the code keep track of the last state we reported
1525 * and just invert the relevant bits in both the report and
1526 * the polarity register.
1527 */
1528 mic_report = wm8903->mic_last_report;
1529 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
1530
1531 if (int_val & WM8903_MICSHRT_EINT) {
1532 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
1533
1534 mic_report ^= wm8903->mic_short;
1535 int_pol ^= WM8903_MICSHRT_INV;
1536 }
1537
1538 if (int_val & WM8903_MICDET_EINT) {
1539 dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol);
1540
1541 mic_report ^= wm8903->mic_det;
1542 int_pol ^= WM8903_MICDET_INV;
1543
1544 msleep(wm8903->mic_delay);
1545 }
1546
1547 snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1,
1548 WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol);
1549
1550 snd_soc_jack_report(wm8903->mic_jack, mic_report,
1551 wm8903->mic_short | wm8903->mic_det);
1552
1553 wm8903->mic_last_report = mic_report;
1554
1555 return IRQ_HANDLED;
1556}
1557
1439#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ 1558#define WM8903_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
1440 SNDRV_PCM_RATE_11025 | \ 1559 SNDRV_PCM_RATE_11025 | \
1441 SNDRV_PCM_RATE_16000 | \ 1560 SNDRV_PCM_RATE_16000 | \
@@ -1510,7 +1629,6 @@ static int wm8903_resume(struct platform_device *pdev)
1510 1629
1511 /* Bring the codec back up to standby first to minimise pop/clicks */ 1630 /* Bring the codec back up to standby first to minimise pop/clicks */
1512 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1631 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1513 wm8903_set_bias_level(codec, codec->suspend_bias_level);
1514 1632
1515 /* Sync back everything else */ 1633 /* Sync back everything else */
1516 if (tmp_cache) { 1634 if (tmp_cache) {
@@ -1530,9 +1648,11 @@ static struct snd_soc_codec *wm8903_codec;
1530static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, 1648static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1531 const struct i2c_device_id *id) 1649 const struct i2c_device_id *id)
1532{ 1650{
1651 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
1533 struct wm8903_priv *wm8903; 1652 struct wm8903_priv *wm8903;
1534 struct snd_soc_codec *codec; 1653 struct snd_soc_codec *codec;
1535 int ret; 1654 int ret, i;
1655 int trigger, irq_pol;
1536 u16 val; 1656 u16 val;
1537 1657
1538 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); 1658 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
@@ -1554,8 +1674,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1554 codec->num_dai = 1; 1674 codec->num_dai = 1;
1555 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache); 1675 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1556 codec->reg_cache = &wm8903->reg_cache[0]; 1676 codec->reg_cache = &wm8903->reg_cache[0];
1557 codec->private_data = wm8903; 1677 snd_soc_codec_set_drvdata(codec, wm8903);
1558 codec->volatile_register = wm8903_volatile_register; 1678 codec->volatile_register = wm8903_volatile_register;
1679 init_completion(&wm8903->wseq);
1559 1680
1560 i2c_set_clientdata(i2c, codec); 1681 i2c_set_clientdata(i2c, codec);
1561 codec->control_data = i2c; 1682 codec->control_data = i2c;
@@ -1579,6 +1700,53 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1579 1700
1580 wm8903_reset(codec); 1701 wm8903_reset(codec);
1581 1702
1703 /* Set up GPIOs and microphone detection */
1704 if (pdata) {
1705 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1706 if (!pdata->gpio_cfg[i])
1707 continue;
1708
1709 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1710 pdata->gpio_cfg[i] & 0xffff);
1711 }
1712
1713 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
1714 pdata->micdet_cfg);
1715
1716 /* Microphone detection needs the WSEQ clock */
1717 if (pdata->micdet_cfg)
1718 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1719 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1720
1721 wm8903->mic_delay = pdata->micdet_delay;
1722 }
1723
1724 if (i2c->irq) {
1725 if (pdata && pdata->irq_active_low) {
1726 trigger = IRQF_TRIGGER_LOW;
1727 irq_pol = WM8903_IRQ_POL;
1728 } else {
1729 trigger = IRQF_TRIGGER_HIGH;
1730 irq_pol = 0;
1731 }
1732
1733 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
1734 WM8903_IRQ_POL, irq_pol);
1735
1736 ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq,
1737 trigger | IRQF_ONESHOT,
1738 "wm8903", wm8903);
1739 if (ret != 0) {
1740 dev_err(&i2c->dev, "Failed to request IRQ: %d\n",
1741 ret);
1742 goto err;
1743 }
1744
1745 /* Enable write sequencer interrupts */
1746 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
1747 WM8903_IM_WSEQ_BUSY_EINT, 0);
1748 }
1749
1582 /* power on device */ 1750 /* power on device */
1583 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1751 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1584 1752
@@ -1619,7 +1787,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1619 ret = snd_soc_register_codec(codec); 1787 ret = snd_soc_register_codec(codec);
1620 if (ret != 0) { 1788 if (ret != 0) {
1621 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); 1789 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1622 goto err; 1790 goto err_irq;
1623 } 1791 }
1624 1792
1625 ret = snd_soc_register_dai(&wm8903_dai); 1793 ret = snd_soc_register_dai(&wm8903_dai);
@@ -1632,6 +1800,9 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1632 1800
1633err_codec: 1801err_codec:
1634 snd_soc_unregister_codec(codec); 1802 snd_soc_unregister_codec(codec);
1803err_irq:
1804 if (i2c->irq)
1805 free_irq(i2c->irq, wm8903);
1635err: 1806err:
1636 wm8903_codec = NULL; 1807 wm8903_codec = NULL;
1637 kfree(wm8903); 1808 kfree(wm8903);
@@ -1641,13 +1812,17 @@ err:
1641static __devexit int wm8903_i2c_remove(struct i2c_client *client) 1812static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1642{ 1813{
1643 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1814 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1815 struct wm8903_priv *priv = snd_soc_codec_get_drvdata(codec);
1644 1816
1645 snd_soc_unregister_dai(&wm8903_dai); 1817 snd_soc_unregister_dai(&wm8903_dai);
1646 snd_soc_unregister_codec(codec); 1818 snd_soc_unregister_codec(codec);
1647 1819
1648 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1820 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1649 1821
1650 kfree(codec->private_data); 1822 if (client->irq)
1823 free_irq(client->irq, priv);
1824
1825 kfree(priv);
1651 1826
1652 wm8903_codec = NULL; 1827 wm8903_codec = NULL;
1653 wm8903_dai.dev = NULL; 1828 wm8903_dai.dev = NULL;
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index 0ea27e2b9963..ce384a2ad820 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -18,6 +18,10 @@
18extern struct snd_soc_dai wm8903_dai; 18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903; 19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20 20
21extern int wm8903_mic_detect(struct snd_soc_codec *codec,
22 struct snd_soc_jack *jack,
23 int det, int shrt);
24
21#define WM8903_MCLK_DIV_2 1 25#define WM8903_MCLK_DIV_2 1
22#define WM8903_CLK_SYS 2 26#define WM8903_CLK_SYS 2
23#define WM8903_BCLK 3 27#define WM8903_BCLK 3
@@ -173,28 +177,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8903;
173#define WM8903_VMID_RES_5K 4 177#define WM8903_VMID_RES_5K 4
174 178
175/* 179/*
176 * R6 (0x06) - Mic Bias Control 0
177 */
178#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */
179#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */
180#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */
181#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
182#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
183#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
184#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
185#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
186#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
187#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
188#define WM8903_MICDET_ENA 0x0002 /* MICDET_ENA */
189#define WM8903_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
190#define WM8903_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
191#define WM8903_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
192#define WM8903_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
193#define WM8903_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
194#define WM8903_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
195#define WM8903_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
196
197/*
198 * R8 (0x08) - Analogue DAC 0 180 * R8 (0x08) - Analogue DAC 0
199 */ 181 */
200#define WM8903_DACBIAS_SEL_MASK 0x0018 /* DACBIAS_SEL - [4:3] */ 182#define WM8903_DACBIAS_SEL_MASK 0x0018 /* DACBIAS_SEL - [4:3] */
@@ -1135,201 +1117,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8903;
1135#define WM8903_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */ 1117#define WM8903_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
1136 1118
1137/* 1119/*
1138 * R116 (0x74) - GPIO Control 1
1139 */
1140#define WM8903_GP1_FN_MASK 0x1F00 /* GP1_FN - [12:8] */
1141#define WM8903_GP1_FN_SHIFT 8 /* GP1_FN - [12:8] */
1142#define WM8903_GP1_FN_WIDTH 5 /* GP1_FN - [12:8] */
1143#define WM8903_GP1_DIR 0x0080 /* GP1_DIR */
1144#define WM8903_GP1_DIR_MASK 0x0080 /* GP1_DIR */
1145#define WM8903_GP1_DIR_SHIFT 7 /* GP1_DIR */
1146#define WM8903_GP1_DIR_WIDTH 1 /* GP1_DIR */
1147#define WM8903_GP1_OP_CFG 0x0040 /* GP1_OP_CFG */
1148#define WM8903_GP1_OP_CFG_MASK 0x0040 /* GP1_OP_CFG */
1149#define WM8903_GP1_OP_CFG_SHIFT 6 /* GP1_OP_CFG */
1150#define WM8903_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
1151#define WM8903_GP1_IP_CFG 0x0020 /* GP1_IP_CFG */
1152#define WM8903_GP1_IP_CFG_MASK 0x0020 /* GP1_IP_CFG */
1153#define WM8903_GP1_IP_CFG_SHIFT 5 /* GP1_IP_CFG */
1154#define WM8903_GP1_IP_CFG_WIDTH 1 /* GP1_IP_CFG */
1155#define WM8903_GP1_LVL 0x0010 /* GP1_LVL */
1156#define WM8903_GP1_LVL_MASK 0x0010 /* GP1_LVL */
1157#define WM8903_GP1_LVL_SHIFT 4 /* GP1_LVL */
1158#define WM8903_GP1_LVL_WIDTH 1 /* GP1_LVL */
1159#define WM8903_GP1_PD 0x0008 /* GP1_PD */
1160#define WM8903_GP1_PD_MASK 0x0008 /* GP1_PD */
1161#define WM8903_GP1_PD_SHIFT 3 /* GP1_PD */
1162#define WM8903_GP1_PD_WIDTH 1 /* GP1_PD */
1163#define WM8903_GP1_PU 0x0004 /* GP1_PU */
1164#define WM8903_GP1_PU_MASK 0x0004 /* GP1_PU */
1165#define WM8903_GP1_PU_SHIFT 2 /* GP1_PU */
1166#define WM8903_GP1_PU_WIDTH 1 /* GP1_PU */
1167#define WM8903_GP1_INTMODE 0x0002 /* GP1_INTMODE */
1168#define WM8903_GP1_INTMODE_MASK 0x0002 /* GP1_INTMODE */
1169#define WM8903_GP1_INTMODE_SHIFT 1 /* GP1_INTMODE */
1170#define WM8903_GP1_INTMODE_WIDTH 1 /* GP1_INTMODE */
1171#define WM8903_GP1_DB 0x0001 /* GP1_DB */
1172#define WM8903_GP1_DB_MASK 0x0001 /* GP1_DB */
1173#define WM8903_GP1_DB_SHIFT 0 /* GP1_DB */
1174#define WM8903_GP1_DB_WIDTH 1 /* GP1_DB */
1175
1176/*
1177 * R117 (0x75) - GPIO Control 2
1178 */
1179#define WM8903_GP2_FN_MASK 0x1F00 /* GP2_FN - [12:8] */
1180#define WM8903_GP2_FN_SHIFT 8 /* GP2_FN - [12:8] */
1181#define WM8903_GP2_FN_WIDTH 5 /* GP2_FN - [12:8] */
1182#define WM8903_GP2_DIR 0x0080 /* GP2_DIR */
1183#define WM8903_GP2_DIR_MASK 0x0080 /* GP2_DIR */
1184#define WM8903_GP2_DIR_SHIFT 7 /* GP2_DIR */
1185#define WM8903_GP2_DIR_WIDTH 1 /* GP2_DIR */
1186#define WM8903_GP2_OP_CFG 0x0040 /* GP2_OP_CFG */
1187#define WM8903_GP2_OP_CFG_MASK 0x0040 /* GP2_OP_CFG */
1188#define WM8903_GP2_OP_CFG_SHIFT 6 /* GP2_OP_CFG */
1189#define WM8903_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
1190#define WM8903_GP2_IP_CFG 0x0020 /* GP2_IP_CFG */
1191#define WM8903_GP2_IP_CFG_MASK 0x0020 /* GP2_IP_CFG */
1192#define WM8903_GP2_IP_CFG_SHIFT 5 /* GP2_IP_CFG */
1193#define WM8903_GP2_IP_CFG_WIDTH 1 /* GP2_IP_CFG */
1194#define WM8903_GP2_LVL 0x0010 /* GP2_LVL */
1195#define WM8903_GP2_LVL_MASK 0x0010 /* GP2_LVL */
1196#define WM8903_GP2_LVL_SHIFT 4 /* GP2_LVL */
1197#define WM8903_GP2_LVL_WIDTH 1 /* GP2_LVL */
1198#define WM8903_GP2_PD 0x0008 /* GP2_PD */
1199#define WM8903_GP2_PD_MASK 0x0008 /* GP2_PD */
1200#define WM8903_GP2_PD_SHIFT 3 /* GP2_PD */
1201#define WM8903_GP2_PD_WIDTH 1 /* GP2_PD */
1202#define WM8903_GP2_PU 0x0004 /* GP2_PU */
1203#define WM8903_GP2_PU_MASK 0x0004 /* GP2_PU */
1204#define WM8903_GP2_PU_SHIFT 2 /* GP2_PU */
1205#define WM8903_GP2_PU_WIDTH 1 /* GP2_PU */
1206#define WM8903_GP2_INTMODE 0x0002 /* GP2_INTMODE */
1207#define WM8903_GP2_INTMODE_MASK 0x0002 /* GP2_INTMODE */
1208#define WM8903_GP2_INTMODE_SHIFT 1 /* GP2_INTMODE */
1209#define WM8903_GP2_INTMODE_WIDTH 1 /* GP2_INTMODE */
1210#define WM8903_GP2_DB 0x0001 /* GP2_DB */
1211#define WM8903_GP2_DB_MASK 0x0001 /* GP2_DB */
1212#define WM8903_GP2_DB_SHIFT 0 /* GP2_DB */
1213#define WM8903_GP2_DB_WIDTH 1 /* GP2_DB */
1214
1215/*
1216 * R118 (0x76) - GPIO Control 3
1217 */
1218#define WM8903_GP3_FN_MASK 0x1F00 /* GP3_FN - [12:8] */
1219#define WM8903_GP3_FN_SHIFT 8 /* GP3_FN - [12:8] */
1220#define WM8903_GP3_FN_WIDTH 5 /* GP3_FN - [12:8] */
1221#define WM8903_GP3_DIR 0x0080 /* GP3_DIR */
1222#define WM8903_GP3_DIR_MASK 0x0080 /* GP3_DIR */
1223#define WM8903_GP3_DIR_SHIFT 7 /* GP3_DIR */
1224#define WM8903_GP3_DIR_WIDTH 1 /* GP3_DIR */
1225#define WM8903_GP3_OP_CFG 0x0040 /* GP3_OP_CFG */
1226#define WM8903_GP3_OP_CFG_MASK 0x0040 /* GP3_OP_CFG */
1227#define WM8903_GP3_OP_CFG_SHIFT 6 /* GP3_OP_CFG */
1228#define WM8903_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
1229#define WM8903_GP3_IP_CFG 0x0020 /* GP3_IP_CFG */
1230#define WM8903_GP3_IP_CFG_MASK 0x0020 /* GP3_IP_CFG */
1231#define WM8903_GP3_IP_CFG_SHIFT 5 /* GP3_IP_CFG */
1232#define WM8903_GP3_IP_CFG_WIDTH 1 /* GP3_IP_CFG */
1233#define WM8903_GP3_LVL 0x0010 /* GP3_LVL */
1234#define WM8903_GP3_LVL_MASK 0x0010 /* GP3_LVL */
1235#define WM8903_GP3_LVL_SHIFT 4 /* GP3_LVL */
1236#define WM8903_GP3_LVL_WIDTH 1 /* GP3_LVL */
1237#define WM8903_GP3_PD 0x0008 /* GP3_PD */
1238#define WM8903_GP3_PD_MASK 0x0008 /* GP3_PD */
1239#define WM8903_GP3_PD_SHIFT 3 /* GP3_PD */
1240#define WM8903_GP3_PD_WIDTH 1 /* GP3_PD */
1241#define WM8903_GP3_PU 0x0004 /* GP3_PU */
1242#define WM8903_GP3_PU_MASK 0x0004 /* GP3_PU */
1243#define WM8903_GP3_PU_SHIFT 2 /* GP3_PU */
1244#define WM8903_GP3_PU_WIDTH 1 /* GP3_PU */
1245#define WM8903_GP3_INTMODE 0x0002 /* GP3_INTMODE */
1246#define WM8903_GP3_INTMODE_MASK 0x0002 /* GP3_INTMODE */
1247#define WM8903_GP3_INTMODE_SHIFT 1 /* GP3_INTMODE */
1248#define WM8903_GP3_INTMODE_WIDTH 1 /* GP3_INTMODE */
1249#define WM8903_GP3_DB 0x0001 /* GP3_DB */
1250#define WM8903_GP3_DB_MASK 0x0001 /* GP3_DB */
1251#define WM8903_GP3_DB_SHIFT 0 /* GP3_DB */
1252#define WM8903_GP3_DB_WIDTH 1 /* GP3_DB */
1253
1254/*
1255 * R119 (0x77) - GPIO Control 4
1256 */
1257#define WM8903_GP4_FN_MASK 0x1F00 /* GP4_FN - [12:8] */
1258#define WM8903_GP4_FN_SHIFT 8 /* GP4_FN - [12:8] */
1259#define WM8903_GP4_FN_WIDTH 5 /* GP4_FN - [12:8] */
1260#define WM8903_GP4_DIR 0x0080 /* GP4_DIR */
1261#define WM8903_GP4_DIR_MASK 0x0080 /* GP4_DIR */
1262#define WM8903_GP4_DIR_SHIFT 7 /* GP4_DIR */
1263#define WM8903_GP4_DIR_WIDTH 1 /* GP4_DIR */
1264#define WM8903_GP4_OP_CFG 0x0040 /* GP4_OP_CFG */
1265#define WM8903_GP4_OP_CFG_MASK 0x0040 /* GP4_OP_CFG */
1266#define WM8903_GP4_OP_CFG_SHIFT 6 /* GP4_OP_CFG */
1267#define WM8903_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
1268#define WM8903_GP4_IP_CFG 0x0020 /* GP4_IP_CFG */
1269#define WM8903_GP4_IP_CFG_MASK 0x0020 /* GP4_IP_CFG */
1270#define WM8903_GP4_IP_CFG_SHIFT 5 /* GP4_IP_CFG */
1271#define WM8903_GP4_IP_CFG_WIDTH 1 /* GP4_IP_CFG */
1272#define WM8903_GP4_LVL 0x0010 /* GP4_LVL */
1273#define WM8903_GP4_LVL_MASK 0x0010 /* GP4_LVL */
1274#define WM8903_GP4_LVL_SHIFT 4 /* GP4_LVL */
1275#define WM8903_GP4_LVL_WIDTH 1 /* GP4_LVL */
1276#define WM8903_GP4_PD 0x0008 /* GP4_PD */
1277#define WM8903_GP4_PD_MASK 0x0008 /* GP4_PD */
1278#define WM8903_GP4_PD_SHIFT 3 /* GP4_PD */
1279#define WM8903_GP4_PD_WIDTH 1 /* GP4_PD */
1280#define WM8903_GP4_PU 0x0004 /* GP4_PU */
1281#define WM8903_GP4_PU_MASK 0x0004 /* GP4_PU */
1282#define WM8903_GP4_PU_SHIFT 2 /* GP4_PU */
1283#define WM8903_GP4_PU_WIDTH 1 /* GP4_PU */
1284#define WM8903_GP4_INTMODE 0x0002 /* GP4_INTMODE */
1285#define WM8903_GP4_INTMODE_MASK 0x0002 /* GP4_INTMODE */
1286#define WM8903_GP4_INTMODE_SHIFT 1 /* GP4_INTMODE */
1287#define WM8903_GP4_INTMODE_WIDTH 1 /* GP4_INTMODE */
1288#define WM8903_GP4_DB 0x0001 /* GP4_DB */
1289#define WM8903_GP4_DB_MASK 0x0001 /* GP4_DB */
1290#define WM8903_GP4_DB_SHIFT 0 /* GP4_DB */
1291#define WM8903_GP4_DB_WIDTH 1 /* GP4_DB */
1292
1293/*
1294 * R120 (0x78) - GPIO Control 5
1295 */
1296#define WM8903_GP5_FN_MASK 0x1F00 /* GP5_FN - [12:8] */
1297#define WM8903_GP5_FN_SHIFT 8 /* GP5_FN - [12:8] */
1298#define WM8903_GP5_FN_WIDTH 5 /* GP5_FN - [12:8] */
1299#define WM8903_GP5_DIR 0x0080 /* GP5_DIR */
1300#define WM8903_GP5_DIR_MASK 0x0080 /* GP5_DIR */
1301#define WM8903_GP5_DIR_SHIFT 7 /* GP5_DIR */
1302#define WM8903_GP5_DIR_WIDTH 1 /* GP5_DIR */
1303#define WM8903_GP5_OP_CFG 0x0040 /* GP5_OP_CFG */
1304#define WM8903_GP5_OP_CFG_MASK 0x0040 /* GP5_OP_CFG */
1305#define WM8903_GP5_OP_CFG_SHIFT 6 /* GP5_OP_CFG */
1306#define WM8903_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
1307#define WM8903_GP5_IP_CFG 0x0020 /* GP5_IP_CFG */
1308#define WM8903_GP5_IP_CFG_MASK 0x0020 /* GP5_IP_CFG */
1309#define WM8903_GP5_IP_CFG_SHIFT 5 /* GP5_IP_CFG */
1310#define WM8903_GP5_IP_CFG_WIDTH 1 /* GP5_IP_CFG */
1311#define WM8903_GP5_LVL 0x0010 /* GP5_LVL */
1312#define WM8903_GP5_LVL_MASK 0x0010 /* GP5_LVL */
1313#define WM8903_GP5_LVL_SHIFT 4 /* GP5_LVL */
1314#define WM8903_GP5_LVL_WIDTH 1 /* GP5_LVL */
1315#define WM8903_GP5_PD 0x0008 /* GP5_PD */
1316#define WM8903_GP5_PD_MASK 0x0008 /* GP5_PD */
1317#define WM8903_GP5_PD_SHIFT 3 /* GP5_PD */
1318#define WM8903_GP5_PD_WIDTH 1 /* GP5_PD */
1319#define WM8903_GP5_PU 0x0004 /* GP5_PU */
1320#define WM8903_GP5_PU_MASK 0x0004 /* GP5_PU */
1321#define WM8903_GP5_PU_SHIFT 2 /* GP5_PU */
1322#define WM8903_GP5_PU_WIDTH 1 /* GP5_PU */
1323#define WM8903_GP5_INTMODE 0x0002 /* GP5_INTMODE */
1324#define WM8903_GP5_INTMODE_MASK 0x0002 /* GP5_INTMODE */
1325#define WM8903_GP5_INTMODE_SHIFT 1 /* GP5_INTMODE */
1326#define WM8903_GP5_INTMODE_WIDTH 1 /* GP5_INTMODE */
1327#define WM8903_GP5_DB 0x0001 /* GP5_DB */
1328#define WM8903_GP5_DB_MASK 0x0001 /* GP5_DB */
1329#define WM8903_GP5_DB_SHIFT 0 /* GP5_DB */
1330#define WM8903_GP5_DB_WIDTH 1 /* GP5_DB */
1331
1332/*
1333 * R121 (0x79) - Interrupt Status 1 1120 * R121 (0x79) - Interrupt Status 1
1334 */ 1121 */
1335#define WM8903_MICSHRT_EINT 0x8000 /* MICSHRT_EINT */ 1122#define WM8903_MICSHRT_EINT 0x8000 /* MICSHRT_EINT */
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index c6f0abcc5711..87f14f8675fa 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -613,7 +613,7 @@ static int wm8904_reset(struct snd_soc_codec *codec)
613 613
614static int wm8904_configure_clocking(struct snd_soc_codec *codec) 614static int wm8904_configure_clocking(struct snd_soc_codec *codec)
615{ 615{
616 struct wm8904_priv *wm8904 = codec->private_data; 616 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
617 unsigned int clock0, clock2, rate; 617 unsigned int clock0, clock2, rate;
618 618
619 /* Gate the clock while we're updating to avoid misclocking */ 619 /* Gate the clock while we're updating to avoid misclocking */
@@ -669,7 +669,7 @@ static int wm8904_configure_clocking(struct snd_soc_codec *codec)
669 669
670static void wm8904_set_drc(struct snd_soc_codec *codec) 670static void wm8904_set_drc(struct snd_soc_codec *codec)
671{ 671{
672 struct wm8904_priv *wm8904 = codec->private_data; 672 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
673 struct wm8904_pdata *pdata = wm8904->pdata; 673 struct wm8904_pdata *pdata = wm8904->pdata;
674 int save, i; 674 int save, i;
675 675
@@ -689,7 +689,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
689 struct snd_ctl_elem_value *ucontrol) 689 struct snd_ctl_elem_value *ucontrol)
690{ 690{
691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 691 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
692 struct wm8904_priv *wm8904 = codec->private_data; 692 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
693 struct wm8904_pdata *pdata = wm8904->pdata; 693 struct wm8904_pdata *pdata = wm8904->pdata;
694 int value = ucontrol->value.integer.value[0]; 694 int value = ucontrol->value.integer.value[0];
695 695
@@ -707,7 +707,7 @@ static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
707 struct snd_ctl_elem_value *ucontrol) 707 struct snd_ctl_elem_value *ucontrol)
708{ 708{
709 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 709 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
710 struct wm8904_priv *wm8904 = codec->private_data; 710 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
711 711
712 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg; 712 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
713 713
@@ -716,7 +716,7 @@ static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
716 716
717static void wm8904_set_retune_mobile(struct snd_soc_codec *codec) 717static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
718{ 718{
719 struct wm8904_priv *wm8904 = codec->private_data; 719 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
720 struct wm8904_pdata *pdata = wm8904->pdata; 720 struct wm8904_pdata *pdata = wm8904->pdata;
721 int best, best_val, save, i, cfg; 721 int best, best_val, save, i, cfg;
722 722
@@ -760,7 +760,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
760 struct snd_ctl_elem_value *ucontrol) 760 struct snd_ctl_elem_value *ucontrol)
761{ 761{
762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 762 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
763 struct wm8904_priv *wm8904 = codec->private_data; 763 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
764 struct wm8904_pdata *pdata = wm8904->pdata; 764 struct wm8904_pdata *pdata = wm8904->pdata;
765 int value = ucontrol->value.integer.value[0]; 765 int value = ucontrol->value.integer.value[0];
766 766
@@ -778,7 +778,7 @@ static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
778 struct snd_ctl_elem_value *ucontrol) 778 struct snd_ctl_elem_value *ucontrol)
779{ 779{
780 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 780 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
781 struct wm8904_priv *wm8904 = codec->private_data; 781 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
782 782
783 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg; 783 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
784 784
@@ -789,7 +789,7 @@ static int deemph_settings[] = { 0, 32000, 44100, 48000 };
789 789
790static int wm8904_set_deemph(struct snd_soc_codec *codec) 790static int wm8904_set_deemph(struct snd_soc_codec *codec)
791{ 791{
792 struct wm8904_priv *wm8904 = codec->private_data; 792 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
793 int val, i, best; 793 int val, i, best;
794 794
795 /* If we're using deemphasis select the nearest available sample 795 /* If we're using deemphasis select the nearest available sample
@@ -818,7 +818,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
818 struct snd_ctl_elem_value *ucontrol) 818 struct snd_ctl_elem_value *ucontrol)
819{ 819{
820 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 820 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
821 struct wm8904_priv *wm8904 = codec->private_data; 821 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
822 822
823 return wm8904->deemph; 823 return wm8904->deemph;
824} 824}
@@ -827,7 +827,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol) 827 struct snd_ctl_elem_value *ucontrol)
828{ 828{
829 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 829 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
830 struct wm8904_priv *wm8904 = codec->private_data; 830 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
831 int deemph = ucontrol->value.enumerated.item[0]; 831 int deemph = ucontrol->value.enumerated.item[0];
832 832
833 if (deemph > 1) 833 if (deemph > 1)
@@ -943,7 +943,7 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
943 struct snd_kcontrol *kcontrol, int event) 943 struct snd_kcontrol *kcontrol, int event)
944{ 944{
945 struct snd_soc_codec *codec = w->codec; 945 struct snd_soc_codec *codec = w->codec;
946 struct wm8904_priv *wm8904 = codec->private_data; 946 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
947 947
948 switch (event) { 948 switch (event) {
949 case SND_SOC_DAPM_PRE_PMU: 949 case SND_SOC_DAPM_PRE_PMU:
@@ -981,7 +981,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
981 struct snd_kcontrol *kcontrol, int event) 981 struct snd_kcontrol *kcontrol, int event)
982{ 982{
983 struct snd_soc_codec *codec = w->codec; 983 struct snd_soc_codec *codec = w->codec;
984 struct wm8904_priv *wm8904 = codec->private_data; 984 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
985 int reg, val; 985 int reg, val;
986 int dcs_mask; 986 int dcs_mask;
987 int dcs_l, dcs_r; 987 int dcs_l, dcs_r;
@@ -1429,7 +1429,7 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = {
1429 1429
1430static int wm8904_add_widgets(struct snd_soc_codec *codec) 1430static int wm8904_add_widgets(struct snd_soc_codec *codec)
1431{ 1431{
1432 struct wm8904_priv *wm8904 = codec->private_data; 1432 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1433 1433
1434 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, 1434 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1435 ARRAY_SIZE(wm8904_core_dapm_widgets)); 1435 ARRAY_SIZE(wm8904_core_dapm_widgets));
@@ -1543,7 +1543,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
1543 struct snd_soc_dai *dai) 1543 struct snd_soc_dai *dai)
1544{ 1544{
1545 struct snd_soc_codec *codec = dai->codec; 1545 struct snd_soc_codec *codec = dai->codec;
1546 struct wm8904_priv *wm8904 = codec->private_data; 1546 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1547 int ret, i, best, best_val, cur_val; 1547 int ret, i, best, best_val, cur_val;
1548 unsigned int aif1 = 0; 1548 unsigned int aif1 = 0;
1549 unsigned int aif2 = 0; 1549 unsigned int aif2 = 0;
@@ -1670,7 +1670,7 @@ static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1670 unsigned int freq, int dir) 1670 unsigned int freq, int dir)
1671{ 1671{
1672 struct snd_soc_codec *codec = dai->codec; 1672 struct snd_soc_codec *codec = dai->codec;
1673 struct wm8904_priv *priv = codec->private_data; 1673 struct wm8904_priv *priv = snd_soc_codec_get_drvdata(codec);
1674 1674
1675 switch (clk_id) { 1675 switch (clk_id) {
1676 case WM8904_CLK_MCLK: 1676 case WM8904_CLK_MCLK:
@@ -1786,7 +1786,7 @@ static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1786 unsigned int rx_mask, int slots, int slot_width) 1786 unsigned int rx_mask, int slots, int slot_width)
1787{ 1787{
1788 struct snd_soc_codec *codec = dai->codec; 1788 struct snd_soc_codec *codec = dai->codec;
1789 struct wm8904_priv *wm8904 = codec->private_data; 1789 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1790 int aif1 = 0; 1790 int aif1 = 0;
1791 1791
1792 /* Don't need to validate anything if we're turning off TDM */ 1792 /* Don't need to validate anything if we're turning off TDM */
@@ -1943,7 +1943,7 @@ static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1943 unsigned int Fref, unsigned int Fout) 1943 unsigned int Fref, unsigned int Fout)
1944{ 1944{
1945 struct snd_soc_codec *codec = dai->codec; 1945 struct snd_soc_codec *codec = dai->codec;
1946 struct wm8904_priv *wm8904 = codec->private_data; 1946 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1947 struct _fll_div fll_div; 1947 struct _fll_div fll_div;
1948 int ret, val; 1948 int ret, val;
1949 int clock2, fll1; 1949 int clock2, fll1;
@@ -2095,7 +2095,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2095 2095
2096static void wm8904_sync_cache(struct snd_soc_codec *codec) 2096static void wm8904_sync_cache(struct snd_soc_codec *codec)
2097{ 2097{
2098 struct wm8904_priv *wm8904 = codec->private_data; 2098 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2099 int i; 2099 int i;
2100 2100
2101 if (!codec->cache_sync) 2101 if (!codec->cache_sync)
@@ -2122,7 +2122,7 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
2122static int wm8904_set_bias_level(struct snd_soc_codec *codec, 2122static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2123 enum snd_soc_bias_level level) 2123 enum snd_soc_bias_level level)
2124{ 2124{
2125 struct wm8904_priv *wm8904 = codec->private_data; 2125 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2126 int ret; 2126 int ret;
2127 2127
2128 switch (level) { 2128 switch (level) {
@@ -2395,7 +2395,7 @@ static int wm8904_probe(struct platform_device *pdev)
2395 goto pcm_err; 2395 goto pcm_err;
2396 } 2396 }
2397 2397
2398 wm8904_handle_pdata(codec->private_data); 2398 wm8904_handle_pdata(snd_soc_codec_get_drvdata(codec));
2399 2399
2400 wm8904_add_widgets(codec); 2400 wm8904_add_widgets(codec);
2401 2401
@@ -2426,6 +2426,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2426static int wm8904_register(struct wm8904_priv *wm8904, 2426static int wm8904_register(struct wm8904_priv *wm8904,
2427 enum snd_soc_control_type control) 2427 enum snd_soc_control_type control)
2428{ 2428{
2429 struct wm8904_pdata *pdata = wm8904->pdata;
2429 int ret; 2430 int ret;
2430 struct snd_soc_codec *codec = &wm8904->codec; 2431 struct snd_soc_codec *codec = &wm8904->codec;
2431 int i; 2432 int i;
@@ -2439,7 +2440,7 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2439 INIT_LIST_HEAD(&codec->dapm_widgets); 2440 INIT_LIST_HEAD(&codec->dapm_widgets);
2440 INIT_LIST_HEAD(&codec->dapm_paths); 2441 INIT_LIST_HEAD(&codec->dapm_paths);
2441 2442
2442 codec->private_data = wm8904; 2443 snd_soc_codec_set_drvdata(codec, wm8904);
2443 codec->name = "WM8904"; 2444 codec->name = "WM8904";
2444 codec->owner = THIS_MODULE; 2445 codec->owner = THIS_MODULE;
2445 codec->bias_level = SND_SOC_BIAS_OFF; 2446 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -2531,6 +2532,22 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2531 WM8904_LINEOUTRZC; 2532 WM8904_LINEOUTRZC;
2532 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; 2533 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
2533 2534
2535 /* Apply configuration from the platform data. */
2536 if (wm8904->pdata) {
2537 for (i = 0; i < WM8904_GPIO_REGS; i++) {
2538 if (!pdata->gpio_cfg[i])
2539 continue;
2540
2541 wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i]
2542 = pdata->gpio_cfg[i] & 0xffff;
2543 }
2544
2545 /* Zero is the default value for these anyway */
2546 for (i = 0; i < WM8904_MIC_REGS; i++)
2547 wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
2548 = pdata->mic_cfg[i];
2549 }
2550
2534 /* Set Class W by default - this will be managed by the Class 2551 /* Set Class W by default - this will be managed by the Class
2535 * G widget at runtime where bypass paths are available. 2552 * G widget at runtime where bypass paths are available.
2536 */ 2553 */
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
index b68886df34e4..abe5059b3004 100644
--- a/sound/soc/codecs/wm8904.h
+++ b/sound/soc/codecs/wm8904.h
@@ -186,39 +186,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8904;
186#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */ 186#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */
187 187
188/* 188/*
189 * R6 (0x06) - Mic Bias Control 0
190 */
191#define WM8904_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
192#define WM8904_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
193#define WM8904_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
194#define WM8904_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
195#define WM8904_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
196#define WM8904_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
197#define WM8904_MICDET_ENA 0x0002 /* MICDET_ENA */
198#define WM8904_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
199#define WM8904_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
200#define WM8904_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
201#define WM8904_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
202#define WM8904_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
203#define WM8904_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
204#define WM8904_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
205
206/*
207 * R7 (0x07) - Mic Bias Control 1
208 */
209#define WM8904_MIC_DET_FILTER_ENA 0x8000 /* MIC_DET_FILTER_ENA */
210#define WM8904_MIC_DET_FILTER_ENA_MASK 0x8000 /* MIC_DET_FILTER_ENA */
211#define WM8904_MIC_DET_FILTER_ENA_SHIFT 15 /* MIC_DET_FILTER_ENA */
212#define WM8904_MIC_DET_FILTER_ENA_WIDTH 1 /* MIC_DET_FILTER_ENA */
213#define WM8904_MIC_SHORT_FILTER_ENA 0x4000 /* MIC_SHORT_FILTER_ENA */
214#define WM8904_MIC_SHORT_FILTER_ENA_MASK 0x4000 /* MIC_SHORT_FILTER_ENA */
215#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT 14 /* MIC_SHORT_FILTER_ENA */
216#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH 1 /* MIC_SHORT_FILTER_ENA */
217#define WM8904_MICBIAS_SEL_MASK 0x0007 /* MICBIAS_SEL - [2:0] */
218#define WM8904_MICBIAS_SEL_SHIFT 0 /* MICBIAS_SEL - [2:0] */
219#define WM8904_MICBIAS_SEL_WIDTH 3 /* MICBIAS_SEL - [2:0] */
220
221/*
222 * R8 (0x08) - Analogue DAC 0 189 * R8 (0x08) - Analogue DAC 0
223 */ 190 */
224#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */ 191#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */
@@ -1200,70 +1167,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8904;
1200#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */ 1167#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
1201 1168
1202/* 1169/*
1203 * R121 (0x79) - GPIO Control 1
1204 */
1205#define WM8904_GPIO1_PU 0x0020 /* GPIO1_PU */
1206#define WM8904_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
1207#define WM8904_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
1208#define WM8904_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
1209#define WM8904_GPIO1_PD 0x0010 /* GPIO1_PD */
1210#define WM8904_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
1211#define WM8904_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
1212#define WM8904_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
1213#define WM8904_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
1214#define WM8904_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
1215#define WM8904_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
1216
1217/*
1218 * R122 (0x7A) - GPIO Control 2
1219 */
1220#define WM8904_GPIO2_PU 0x0020 /* GPIO2_PU */
1221#define WM8904_GPIO2_PU_MASK 0x0020 /* GPIO2_PU */
1222#define WM8904_GPIO2_PU_SHIFT 5 /* GPIO2_PU */
1223#define WM8904_GPIO2_PU_WIDTH 1 /* GPIO2_PU */
1224#define WM8904_GPIO2_PD 0x0010 /* GPIO2_PD */
1225#define WM8904_GPIO2_PD_MASK 0x0010 /* GPIO2_PD */
1226#define WM8904_GPIO2_PD_SHIFT 4 /* GPIO2_PD */
1227#define WM8904_GPIO2_PD_WIDTH 1 /* GPIO2_PD */
1228#define WM8904_GPIO2_SEL_MASK 0x000F /* GPIO2_SEL - [3:0] */
1229#define WM8904_GPIO2_SEL_SHIFT 0 /* GPIO2_SEL - [3:0] */
1230#define WM8904_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [3:0] */
1231
1232/*
1233 * R123 (0x7B) - GPIO Control 3
1234 */
1235#define WM8904_GPIO3_PU 0x0020 /* GPIO3_PU */
1236#define WM8904_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */
1237#define WM8904_GPIO3_PU_SHIFT 5 /* GPIO3_PU */
1238#define WM8904_GPIO3_PU_WIDTH 1 /* GPIO3_PU */
1239#define WM8904_GPIO3_PD 0x0010 /* GPIO3_PD */
1240#define WM8904_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */
1241#define WM8904_GPIO3_PD_SHIFT 4 /* GPIO3_PD */
1242#define WM8904_GPIO3_PD_WIDTH 1 /* GPIO3_PD */
1243#define WM8904_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
1244#define WM8904_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */
1245#define WM8904_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */
1246
1247/*
1248 * R124 (0x7C) - GPIO Control 4
1249 */
1250#define WM8904_GPI7_ENA 0x0200 /* GPI7_ENA */
1251#define WM8904_GPI7_ENA_MASK 0x0200 /* GPI7_ENA */
1252#define WM8904_GPI7_ENA_SHIFT 9 /* GPI7_ENA */
1253#define WM8904_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
1254#define WM8904_GPI8_ENA 0x0100 /* GPI8_ENA */
1255#define WM8904_GPI8_ENA_MASK 0x0100 /* GPI8_ENA */
1256#define WM8904_GPI8_ENA_SHIFT 8 /* GPI8_ENA */
1257#define WM8904_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
1258#define WM8904_GPIO_BCLK_MODE_ENA 0x0080 /* GPIO_BCLK_MODE_ENA */
1259#define WM8904_GPIO_BCLK_MODE_ENA_MASK 0x0080 /* GPIO_BCLK_MODE_ENA */
1260#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT 7 /* GPIO_BCLK_MODE_ENA */
1261#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH 1 /* GPIO_BCLK_MODE_ENA */
1262#define WM8904_GPIO_BCLK_SEL_MASK 0x000F /* GPIO_BCLK_SEL - [3:0] */
1263#define WM8904_GPIO_BCLK_SEL_SHIFT 0 /* GPIO_BCLK_SEL - [3:0] */
1264#define WM8904_GPIO_BCLK_SEL_WIDTH 4 /* GPIO_BCLK_SEL - [3:0] */
1265
1266/*
1267 * R126 (0x7E) - Digital Pulls 1170 * R126 (0x7E) - Digital Pulls
1268 */ 1171 */
1269#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */ 1172#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 0c04b476487f..e3c4bbfaae27 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -581,7 +581,7 @@ static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai,
581 int clk_id, unsigned int freq, int dir) 581 int clk_id, unsigned int freq, int dir)
582{ 582{
583 struct snd_soc_codec *codec = codec_dai->codec; 583 struct snd_soc_codec *codec = codec_dai->codec;
584 struct wm8940_priv *wm8940 = codec->private_data; 584 struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec);
585 585
586 switch (freq) { 586 switch (freq) {
587 case 11289600: 587 case 11289600:
@@ -692,7 +692,6 @@ static int wm8940_resume(struct platform_device *pdev)
692 ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 692 ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
693 if (ret) 693 if (ret)
694 goto error_ret; 694 goto error_ret;
695 ret = wm8940_set_bias_level(codec, codec->suspend_bias_level);
696 695
697error_ret: 696error_ret:
698 return ret; 697 return ret;
@@ -773,7 +772,7 @@ static int wm8940_register(struct wm8940_priv *wm8940,
773 INIT_LIST_HEAD(&codec->dapm_widgets); 772 INIT_LIST_HEAD(&codec->dapm_widgets);
774 INIT_LIST_HEAD(&codec->dapm_paths); 773 INIT_LIST_HEAD(&codec->dapm_paths);
775 774
776 codec->private_data = wm8940; 775 snd_soc_codec_set_drvdata(codec, wm8940);
777 codec->name = "WM8940"; 776 codec->name = "WM8940";
778 codec->owner = THIS_MODULE; 777 codec->owner = THIS_MODULE;
779 codec->bias_level = SND_SOC_BIAS_OFF; 778 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index c8d7a809af4d..fedb76452f1b 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -235,7 +235,7 @@ static struct {
235 235
236static int wm8955_configure_clocking(struct snd_soc_codec *codec) 236static int wm8955_configure_clocking(struct snd_soc_codec *codec)
237{ 237{
238 struct wm8955_priv *wm8955 = codec->private_data; 238 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
239 int i, ret, val; 239 int i, ret, val;
240 int clocking = 0; 240 int clocking = 0;
241 int srate = 0; 241 int srate = 0;
@@ -353,7 +353,7 @@ static int deemph_settings[] = { 0, 32000, 44100, 48000 };
353 353
354static int wm8955_set_deemph(struct snd_soc_codec *codec) 354static int wm8955_set_deemph(struct snd_soc_codec *codec)
355{ 355{
356 struct wm8955_priv *wm8955 = codec->private_data; 356 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
357 int val, i, best; 357 int val, i, best;
358 358
359 /* If we're using deemphasis select the nearest available sample 359 /* If we're using deemphasis select the nearest available sample
@@ -382,7 +382,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol) 382 struct snd_ctl_elem_value *ucontrol)
383{ 383{
384 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 384 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
385 struct wm8955_priv *wm8955 = codec->private_data; 385 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
386 386
387 return wm8955->deemph; 387 return wm8955->deemph;
388} 388}
@@ -391,7 +391,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol) 391 struct snd_ctl_elem_value *ucontrol)
392{ 392{
393 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 393 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
394 struct wm8955_priv *wm8955 = codec->private_data; 394 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
395 int deemph = ucontrol->value.enumerated.item[0]; 395 int deemph = ucontrol->value.enumerated.item[0];
396 396
397 if (deemph > 1) 397 if (deemph > 1)
@@ -598,7 +598,7 @@ static int wm8955_hw_params(struct snd_pcm_substream *substream,
598 struct snd_soc_dai *dai) 598 struct snd_soc_dai *dai)
599{ 599{
600 struct snd_soc_codec *codec = dai->codec; 600 struct snd_soc_codec *codec = dai->codec;
601 struct wm8955_priv *wm8955 = codec->private_data; 601 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
602 int ret; 602 int ret;
603 int wl; 603 int wl;
604 604
@@ -647,7 +647,7 @@ static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
647 unsigned int freq, int dir) 647 unsigned int freq, int dir)
648{ 648{
649 struct snd_soc_codec *codec = dai->codec; 649 struct snd_soc_codec *codec = dai->codec;
650 struct wm8955_priv *priv = codec->private_data; 650 struct wm8955_priv *priv = snd_soc_codec_get_drvdata(codec);
651 int div; 651 int div;
652 652
653 switch (clk_id) { 653 switch (clk_id) {
@@ -770,7 +770,7 @@ static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
770static int wm8955_set_bias_level(struct snd_soc_codec *codec, 770static int wm8955_set_bias_level(struct snd_soc_codec *codec,
771 enum snd_soc_bias_level level) 771 enum snd_soc_bias_level level)
772{ 772{
773 struct wm8955_priv *wm8955 = codec->private_data; 773 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
774 int ret, i; 774 int ret, i;
775 775
776 switch (level) { 776 switch (level) {
@@ -971,7 +971,7 @@ static int wm8955_register(struct wm8955_priv *wm8955,
971 INIT_LIST_HEAD(&codec->dapm_widgets); 971 INIT_LIST_HEAD(&codec->dapm_widgets);
972 INIT_LIST_HEAD(&codec->dapm_paths); 972 INIT_LIST_HEAD(&codec->dapm_paths);
973 973
974 codec->private_data = wm8955; 974 snd_soc_codec_set_drvdata(codec, wm8955);
975 codec->name = "WM8955"; 975 codec->name = "WM8955";
976 codec->owner = THIS_MODULE; 976 codec->owner = THIS_MODULE;
977 codec->bias_level = SND_SOC_BIAS_OFF; 977 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f1e63e01b04d..7233cc68435a 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -23,6 +23,7 @@
23#include <sound/soc-dapm.h> 23#include <sound/soc-dapm.h>
24#include <sound/initval.h> 24#include <sound/initval.h>
25#include <sound/tlv.h> 25#include <sound/tlv.h>
26#include <sound/wm8960.h>
26 27
27#include "wm8960.h" 28#include "wm8960.h"
28 29
@@ -31,8 +32,14 @@
31struct snd_soc_codec_device soc_codec_dev_wm8960; 32struct snd_soc_codec_device soc_codec_dev_wm8960;
32 33
33/* R25 - Power 1 */ 34/* R25 - Power 1 */
35#define WM8960_VMID_MASK 0x180
34#define WM8960_VREF 0x40 36#define WM8960_VREF 0x40
35 37
38/* R26 - Power 2 */
39#define WM8960_PWR2_LOUT1 0x40
40#define WM8960_PWR2_ROUT1 0x20
41#define WM8960_PWR2_OUT3 0x02
42
36/* R28 - Anti-pop 1 */ 43/* R28 - Anti-pop 1 */
37#define WM8960_POBCTRL 0x80 44#define WM8960_POBCTRL 0x80
38#define WM8960_BUFDCOPEN 0x10 45#define WM8960_BUFDCOPEN 0x10
@@ -42,6 +49,7 @@ struct snd_soc_codec_device soc_codec_dev_wm8960;
42 49
43/* R29 - Anti-pop 2 */ 50/* R29 - Anti-pop 2 */
44#define WM8960_DISOP 0x40 51#define WM8960_DISOP 0x40
52#define WM8960_DRES_MASK 0x30
45 53
46/* 54/*
47 * wm8960 register cache 55 * wm8960 register cache
@@ -68,6 +76,9 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
68struct wm8960_priv { 76struct wm8960_priv {
69 u16 reg_cache[WM8960_CACHEREGNUM]; 77 u16 reg_cache[WM8960_CACHEREGNUM];
70 struct snd_soc_codec codec; 78 struct snd_soc_codec codec;
79 struct snd_soc_dapm_widget *lout1;
80 struct snd_soc_dapm_widget *rout1;
81 struct snd_soc_dapm_widget *out3;
71}; 82};
72 83
73#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0) 84#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
@@ -226,10 +237,6 @@ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0,
226 &wm8960_routput_mixer[0], 237 &wm8960_routput_mixer[0],
227 ARRAY_SIZE(wm8960_routput_mixer)), 238 ARRAY_SIZE(wm8960_routput_mixer)),
228 239
229SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
230 &wm8960_mono_out[0],
231 ARRAY_SIZE(wm8960_mono_out)),
232
233SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0), 240SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0),
234SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0), 241SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0),
235 242
@@ -248,6 +255,17 @@ SND_SOC_DAPM_OUTPUT("SPK_RN"),
248SND_SOC_DAPM_OUTPUT("OUT3"), 255SND_SOC_DAPM_OUTPUT("OUT3"),
249}; 256};
250 257
258static const struct snd_soc_dapm_widget wm8960_dapm_widgets_out3[] = {
259SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0,
260 &wm8960_mono_out[0],
261 ARRAY_SIZE(wm8960_mono_out)),
262};
263
264/* Represent OUT3 as a PGA so that it gets turned on with LOUT1/ROUT1 */
265static const struct snd_soc_dapm_widget wm8960_dapm_widgets_capless[] = {
266SND_SOC_DAPM_PGA("OUT3 VMID", WM8960_POWER2, 1, 0, NULL, 0),
267};
268
251static const struct snd_soc_dapm_route audio_paths[] = { 269static const struct snd_soc_dapm_route audio_paths[] = {
252 { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" }, 270 { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" },
253 { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" }, 271 { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" },
@@ -278,9 +296,6 @@ static const struct snd_soc_dapm_route audio_paths[] = {
278 { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } , 296 { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } ,
279 { "Right Output Mixer", "PCM Playback Switch", "Right DAC" }, 297 { "Right Output Mixer", "PCM Playback Switch", "Right DAC" },
280 298
281 { "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
282 { "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
283
284 { "LOUT1 PGA", NULL, "Left Output Mixer" }, 299 { "LOUT1 PGA", NULL, "Left Output Mixer" },
285 { "ROUT1 PGA", NULL, "Right Output Mixer" }, 300 { "ROUT1 PGA", NULL, "Right Output Mixer" },
286 301
@@ -297,17 +312,65 @@ static const struct snd_soc_dapm_route audio_paths[] = {
297 { "SPK_LP", NULL, "Left Speaker Output" }, 312 { "SPK_LP", NULL, "Left Speaker Output" },
298 { "SPK_RN", NULL, "Right Speaker Output" }, 313 { "SPK_RN", NULL, "Right Speaker Output" },
299 { "SPK_RP", NULL, "Right Speaker Output" }, 314 { "SPK_RP", NULL, "Right Speaker Output" },
315};
316
317static const struct snd_soc_dapm_route audio_paths_out3[] = {
318 { "Mono Output Mixer", "Left Switch", "Left Output Mixer" },
319 { "Mono Output Mixer", "Right Switch", "Right Output Mixer" },
300 320
301 { "OUT3", NULL, "Mono Output Mixer", } 321 { "OUT3", NULL, "Mono Output Mixer", }
302}; 322};
303 323
324static const struct snd_soc_dapm_route audio_paths_capless[] = {
325 { "HP_L", NULL, "OUT3 VMID" },
326 { "HP_R", NULL, "OUT3 VMID" },
327
328 { "OUT3 VMID", NULL, "Left Output Mixer" },
329 { "OUT3 VMID", NULL, "Right Output Mixer" },
330};
331
304static int wm8960_add_widgets(struct snd_soc_codec *codec) 332static int wm8960_add_widgets(struct snd_soc_codec *codec)
305{ 333{
334 struct wm8960_data *pdata = codec->dev->platform_data;
335 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
336 struct snd_soc_dapm_widget *w;
337
306 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, 338 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets,
307 ARRAY_SIZE(wm8960_dapm_widgets)); 339 ARRAY_SIZE(wm8960_dapm_widgets));
308 340
309 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 341 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
310 342
343 /* In capless mode OUT3 is used to provide VMID for the
344 * headphone outputs, otherwise it is used as a mono mixer.
345 */
346 if (pdata && pdata->capless) {
347 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless,
348 ARRAY_SIZE(wm8960_dapm_widgets_capless));
349
350 snd_soc_dapm_add_routes(codec, audio_paths_capless,
351 ARRAY_SIZE(audio_paths_capless));
352 } else {
353 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3,
354 ARRAY_SIZE(wm8960_dapm_widgets_out3));
355
356 snd_soc_dapm_add_routes(codec, audio_paths_out3,
357 ARRAY_SIZE(audio_paths_out3));
358 }
359
360 /* We need to power up the headphone output stage out of
361 * sequence for capless mode. To save scanning the widget
362 * list each time to find the desired power state do so now
363 * and save the result.
364 */
365 list_for_each_entry(w, &codec->dapm_widgets, list) {
366 if (strcmp(w->name, "LOUT1 PGA") == 0)
367 wm8960->lout1 = w;
368 if (strcmp(w->name, "ROUT1 PGA") == 0)
369 wm8960->rout1 = w;
370 if (strcmp(w->name, "OUT3 VMID") == 0)
371 wm8960->out3 = w;
372 }
373
311 return 0; 374 return 0;
312} 375}
313 376
@@ -408,10 +471,9 @@ static int wm8960_mute(struct snd_soc_dai *dai, int mute)
408 return 0; 471 return 0;
409} 472}
410 473
411static int wm8960_set_bias_level(struct snd_soc_codec *codec, 474static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
412 enum snd_soc_bias_level level) 475 enum snd_soc_bias_level level)
413{ 476{
414 struct wm8960_data *pdata = codec->dev->platform_data;
415 u16 reg; 477 u16 reg;
416 478
417 switch (level) { 479 switch (level) {
@@ -430,18 +492,8 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
430 if (codec->bias_level == SND_SOC_BIAS_OFF) { 492 if (codec->bias_level == SND_SOC_BIAS_OFF) {
431 /* Enable anti-pop features */ 493 /* Enable anti-pop features */
432 snd_soc_write(codec, WM8960_APOP1, 494 snd_soc_write(codec, WM8960_APOP1,
433 WM8960_POBCTRL | WM8960_SOFT_ST | 495 WM8960_POBCTRL | WM8960_SOFT_ST |
434 WM8960_BUFDCOPEN | WM8960_BUFIOEN); 496 WM8960_BUFDCOPEN | WM8960_BUFIOEN);
435
436 /* Discharge HP output */
437 reg = WM8960_DISOP;
438 if (pdata)
439 reg |= pdata->dres << 4;
440 snd_soc_write(codec, WM8960_APOP2, reg);
441
442 msleep(400);
443
444 snd_soc_write(codec, WM8960_APOP2, 0);
445 497
446 /* Enable & ramp VMID at 2x50k */ 498 /* Enable & ramp VMID at 2x50k */
447 reg = snd_soc_read(codec, WM8960_POWER1); 499 reg = snd_soc_read(codec, WM8960_POWER1);
@@ -472,8 +524,101 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
472 /* Disable VMID and VREF, let them discharge */ 524 /* Disable VMID and VREF, let them discharge */
473 snd_soc_write(codec, WM8960_POWER1, 0); 525 snd_soc_write(codec, WM8960_POWER1, 0);
474 msleep(600); 526 msleep(600);
527 break;
528 }
529
530 codec->bias_level = level;
531
532 return 0;
533}
534
535static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
536 enum snd_soc_bias_level level)
537{
538 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
539 int reg;
540
541 switch (level) {
542 case SND_SOC_BIAS_ON:
543 break;
544
545 case SND_SOC_BIAS_PREPARE:
546 switch (codec->bias_level) {
547 case SND_SOC_BIAS_STANDBY:
548 /* Enable anti pop mode */
549 snd_soc_update_bits(codec, WM8960_APOP1,
550 WM8960_POBCTRL | WM8960_SOFT_ST |
551 WM8960_BUFDCOPEN,
552 WM8960_POBCTRL | WM8960_SOFT_ST |
553 WM8960_BUFDCOPEN);
554
555 /* Enable LOUT1, ROUT1 and OUT3 if they're enabled */
556 reg = 0;
557 if (wm8960->lout1 && wm8960->lout1->power)
558 reg |= WM8960_PWR2_LOUT1;
559 if (wm8960->rout1 && wm8960->rout1->power)
560 reg |= WM8960_PWR2_ROUT1;
561 if (wm8960->out3 && wm8960->out3->power)
562 reg |= WM8960_PWR2_OUT3;
563 snd_soc_update_bits(codec, WM8960_POWER2,
564 WM8960_PWR2_LOUT1 |
565 WM8960_PWR2_ROUT1 |
566 WM8960_PWR2_OUT3, reg);
567
568 /* Enable VMID at 2*50k */
569 snd_soc_update_bits(codec, WM8960_POWER1,
570 WM8960_VMID_MASK, 0x80);
571
572 /* Ramp */
573 msleep(100);
574
575 /* Enable VREF */
576 snd_soc_update_bits(codec, WM8960_POWER1,
577 WM8960_VREF, WM8960_VREF);
578
579 msleep(100);
580 break;
581
582 case SND_SOC_BIAS_ON:
583 /* Enable anti-pop mode */
584 snd_soc_update_bits(codec, WM8960_APOP1,
585 WM8960_POBCTRL | WM8960_SOFT_ST |
586 WM8960_BUFDCOPEN,
587 WM8960_POBCTRL | WM8960_SOFT_ST |
588 WM8960_BUFDCOPEN);
589
590 /* Disable VMID and VREF */
591 snd_soc_update_bits(codec, WM8960_POWER1,
592 WM8960_VREF | WM8960_VMID_MASK, 0);
593 break;
594
595 default:
596 break;
597 }
598 break;
475 599
476 snd_soc_write(codec, WM8960_APOP1, 0); 600 case SND_SOC_BIAS_STANDBY:
601 switch (codec->bias_level) {
602 case SND_SOC_BIAS_PREPARE:
603 /* Disable HP discharge */
604 snd_soc_update_bits(codec, WM8960_APOP2,
605 WM8960_DISOP | WM8960_DRES_MASK,
606 0);
607
608 /* Disable anti-pop features */
609 snd_soc_update_bits(codec, WM8960_APOP1,
610 WM8960_POBCTRL | WM8960_SOFT_ST |
611 WM8960_BUFDCOPEN,
612 WM8960_POBCTRL | WM8960_SOFT_ST |
613 WM8960_BUFDCOPEN);
614 break;
615
616 default:
617 break;
618 }
619 break;
620
621 case SND_SOC_BIAS_OFF:
477 break; 622 break;
478 } 623 }
479 624
@@ -594,10 +739,6 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
594 u16 reg; 739 u16 reg;
595 740
596 switch (div_id) { 741 switch (div_id) {
597 case WM8960_SYSCLKSEL:
598 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1fe;
599 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
600 break;
601 case WM8960_SYSCLKDIV: 742 case WM8960_SYSCLKDIV:
602 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9; 743 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9;
603 snd_soc_write(codec, WM8960_CLOCK1, reg | div); 744 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
@@ -663,7 +804,7 @@ static int wm8960_suspend(struct platform_device *pdev, pm_message_t state)
663 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 804 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
664 struct snd_soc_codec *codec = socdev->card->codec; 805 struct snd_soc_codec *codec = socdev->card->codec;
665 806
666 wm8960_set_bias_level(codec, SND_SOC_BIAS_OFF); 807 codec->set_bias_level(codec, SND_SOC_BIAS_OFF);
667 return 0; 808 return 0;
668} 809}
669 810
@@ -682,8 +823,8 @@ static int wm8960_resume(struct platform_device *pdev)
682 codec->hw_write(codec->control_data, data, 2); 823 codec->hw_write(codec->control_data, data, 2);
683 } 824 }
684 825
685 wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 826 codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
686 wm8960_set_bias_level(codec, codec->suspend_bias_level); 827
687 return 0; 828 return 0;
688} 829}
689 830
@@ -753,6 +894,8 @@ static int wm8960_register(struct wm8960_priv *wm8960,
753 goto err; 894 goto err;
754 } 895 }
755 896
897 codec->set_bias_level = wm8960_set_bias_level_out3;
898
756 if (!pdata) { 899 if (!pdata) {
757 dev_warn(codec->dev, "No platform data supplied\n"); 900 dev_warn(codec->dev, "No platform data supplied\n");
758 } else { 901 } else {
@@ -760,17 +903,19 @@ static int wm8960_register(struct wm8960_priv *wm8960,
760 dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres); 903 dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres);
761 pdata->dres = 0; 904 pdata->dres = 0;
762 } 905 }
906
907 if (pdata->capless)
908 codec->set_bias_level = wm8960_set_bias_level_capless;
763 } 909 }
764 910
765 mutex_init(&codec->mutex); 911 mutex_init(&codec->mutex);
766 INIT_LIST_HEAD(&codec->dapm_widgets); 912 INIT_LIST_HEAD(&codec->dapm_widgets);
767 INIT_LIST_HEAD(&codec->dapm_paths); 913 INIT_LIST_HEAD(&codec->dapm_paths);
768 914
769 codec->private_data = wm8960; 915 snd_soc_codec_set_drvdata(codec, wm8960);
770 codec->name = "WM8960"; 916 codec->name = "WM8960";
771 codec->owner = THIS_MODULE; 917 codec->owner = THIS_MODULE;
772 codec->bias_level = SND_SOC_BIAS_OFF; 918 codec->bias_level = SND_SOC_BIAS_OFF;
773 codec->set_bias_level = wm8960_set_bias_level;
774 codec->dai = &wm8960_dai; 919 codec->dai = &wm8960_dai;
775 codec->num_dai = 1; 920 codec->num_dai = 1;
776 codec->reg_cache_size = WM8960_CACHEREGNUM; 921 codec->reg_cache_size = WM8960_CACHEREGNUM;
@@ -792,7 +937,7 @@ static int wm8960_register(struct wm8960_priv *wm8960,
792 937
793 wm8960_dai.dev = codec->dev; 938 wm8960_dai.dev = codec->dev;
794 939
795 wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 940 codec->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
796 941
797 /* Latch the update bits */ 942 /* Latch the update bits */
798 reg = snd_soc_read(codec, WM8960_LINVOL); 943 reg = snd_soc_read(codec, WM8960_LINVOL);
@@ -841,7 +986,7 @@ err:
841 986
842static void wm8960_unregister(struct wm8960_priv *wm8960) 987static void wm8960_unregister(struct wm8960_priv *wm8960)
843{ 988{
844 wm8960_set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF); 989 wm8960->codec.set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF);
845 snd_soc_unregister_dai(&wm8960_dai); 990 snd_soc_unregister_dai(&wm8960_dai);
846 snd_soc_unregister_codec(&wm8960->codec); 991 snd_soc_unregister_codec(&wm8960->codec);
847 kfree(wm8960); 992 kfree(wm8960);
@@ -883,7 +1028,7 @@ MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
883 1028
884static struct i2c_driver wm8960_i2c_driver = { 1029static struct i2c_driver wm8960_i2c_driver = {
885 .driver = { 1030 .driver = {
886 .name = "WM8960 I2C Codec", 1031 .name = "wm8960",
887 .owner = THIS_MODULE, 1032 .owner = THIS_MODULE,
888 }, 1033 },
889 .probe = wm8960_i2c_probe, 1034 .probe = wm8960_i2c_probe,
diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h
index c9af56c9d9d4..a5ef65481b86 100644
--- a/sound/soc/codecs/wm8960.h
+++ b/sound/soc/codecs/wm8960.h
@@ -76,7 +76,6 @@
76#define WM8960_OPCLKDIV 2 76#define WM8960_OPCLKDIV 2
77#define WM8960_DCLKDIV 3 77#define WM8960_DCLKDIV 3
78#define WM8960_TOCLKSEL 4 78#define WM8960_TOCLKSEL 4
79#define WM8960_SYSCLKSEL 5
80 79
81#define WM8960_SYSCLK_DIV_1 (0 << 1) 80#define WM8960_SYSCLK_DIV_1 (0 << 1)
82#define WM8960_SYSCLK_DIV_2 (2 << 1) 81#define WM8960_SYSCLK_DIV_2 (2 << 1)
@@ -114,14 +113,4 @@
114extern struct snd_soc_dai wm8960_dai; 113extern struct snd_soc_dai wm8960_dai;
115extern struct snd_soc_codec_device soc_codec_dev_wm8960; 114extern struct snd_soc_codec_device soc_codec_dev_wm8960;
116 115
117#define WM8960_DRES_400R 0
118#define WM8960_DRES_200R 1
119#define WM8960_DRES_600R 2
120#define WM8960_DRES_150R 3
121#define WM8960_DRES_MAX 3
122
123struct wm8960_data {
124 int dres;
125};
126
127#endif 116#endif
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 50634ab76a5c..5b9a756242f1 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -631,7 +631,7 @@ static int wm8961_hw_params(struct snd_pcm_substream *substream,
631 struct snd_soc_dai *dai) 631 struct snd_soc_dai *dai)
632{ 632{
633 struct snd_soc_codec *codec = dai->codec; 633 struct snd_soc_codec *codec = dai->codec;
634 struct wm8961_priv *wm8961 = codec->private_data; 634 struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
635 int i, best, target, fs; 635 int i, best, target, fs;
636 u16 reg; 636 u16 reg;
637 637
@@ -722,7 +722,7 @@ static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
722 int dir) 722 int dir)
723{ 723{
724 struct snd_soc_codec *codec = dai->codec; 724 struct snd_soc_codec *codec = dai->codec;
725 struct wm8961_priv *wm8961 = codec->private_data; 725 struct wm8961_priv *wm8961 = snd_soc_codec_get_drvdata(codec);
726 u16 reg = snd_soc_read(codec, WM8961_CLOCKING1); 726 u16 reg = snd_soc_read(codec, WM8961_CLOCKING1);
727 727
728 if (freq > 33000000) { 728 if (freq > 33000000) {
@@ -1065,7 +1065,7 @@ static int wm8961_register(struct wm8961_priv *wm8961)
1065 INIT_LIST_HEAD(&codec->dapm_widgets); 1065 INIT_LIST_HEAD(&codec->dapm_widgets);
1066 INIT_LIST_HEAD(&codec->dapm_paths); 1066 INIT_LIST_HEAD(&codec->dapm_paths);
1067 1067
1068 codec->private_data = wm8961; 1068 snd_soc_codec_set_drvdata(codec, wm8961);
1069 codec->name = "WM8961"; 1069 codec->name = "WM8961";
1070 codec->owner = THIS_MODULE; 1070 codec->owner = THIS_MODULE;
1071 codec->dai = &wm8961_dai; 1071 codec->dai = &wm8961_dai;
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index a65b781af512..a99620f335d2 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -415,7 +415,7 @@ static int wm8971_set_dai_sysclk(struct snd_soc_dai *codec_dai,
415 int clk_id, unsigned int freq, int dir) 415 int clk_id, unsigned int freq, int dir)
416{ 416{
417 struct snd_soc_codec *codec = codec_dai->codec; 417 struct snd_soc_codec *codec = codec_dai->codec;
418 struct wm8971_priv *wm8971 = codec->private_data; 418 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
419 419
420 switch (freq) { 420 switch (freq) {
421 case 11289600: 421 case 11289600:
@@ -494,7 +494,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
494 struct snd_soc_pcm_runtime *rtd = substream->private_data; 494 struct snd_soc_pcm_runtime *rtd = substream->private_data;
495 struct snd_soc_device *socdev = rtd->socdev; 495 struct snd_soc_device *socdev = rtd->socdev;
496 struct snd_soc_codec *codec = socdev->card->codec; 496 struct snd_soc_codec *codec = socdev->card->codec;
497 struct wm8971_priv *wm8971 = codec->private_data; 497 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
498 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3; 498 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
499 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0; 499 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
500 int coeff = get_coeff(wm8971->sysclk, params_rate(params)); 500 int coeff = get_coeff(wm8971->sysclk, params_rate(params));
@@ -820,7 +820,7 @@ static int wm8971_probe(struct platform_device *pdev)
820 return -ENOMEM; 820 return -ENOMEM;
821 } 821 }
822 822
823 codec->private_data = wm8971; 823 snd_soc_codec_set_drvdata(codec, wm8971);
824 socdev->card->codec = codec; 824 socdev->card->codec = codec;
825 mutex_init(&codec->mutex); 825 mutex_init(&codec->mutex);
826 INIT_LIST_HEAD(&codec->dapm_widgets); 826 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -830,7 +830,7 @@ static int wm8971_probe(struct platform_device *pdev)
830 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work); 830 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
831 wm8971_workq = create_workqueue("wm8971"); 831 wm8971_workq = create_workqueue("wm8971");
832 if (wm8971_workq == NULL) { 832 if (wm8971_workq == NULL) {
833 kfree(codec->private_data); 833 kfree(snd_soc_codec_get_drvdata(codec));
834 kfree(codec); 834 kfree(codec);
835 return -ENOMEM; 835 return -ENOMEM;
836 } 836 }
@@ -844,7 +844,7 @@ static int wm8971_probe(struct platform_device *pdev)
844 844
845 if (ret != 0) { 845 if (ret != 0) {
846 destroy_workqueue(wm8971_workq); 846 destroy_workqueue(wm8971_workq);
847 kfree(codec->private_data); 847 kfree(snd_soc_codec_get_drvdata(codec));
848 kfree(codec); 848 kfree(codec);
849 } 849 }
850 850
@@ -867,7 +867,7 @@ static int wm8971_remove(struct platform_device *pdev)
867 i2c_unregister_device(codec->control_data); 867 i2c_unregister_device(codec->control_data);
868 i2c_del_driver(&wm8971_i2c_driver); 868 i2c_del_driver(&wm8971_i2c_driver);
869#endif 869#endif
870 kfree(codec->private_data); 870 kfree(snd_soc_codec_get_drvdata(codec));
871 kfree(codec); 871 kfree(codec);
872 872
873 return 0; 873 return 0;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 69708c4cc004..a2c4b2f37cca 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -181,7 +181,7 @@ SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 8, 1, 0),
181static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = { 181static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = {
182SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0), 182SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0),
183SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0), 183SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0),
184SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 1), 184SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 0),
185}; 185};
186 186
187/* Mono Output Mixer */ 187/* Mono Output Mixer */
@@ -609,7 +609,7 @@ static int wm8974_resume(struct platform_device *pdev)
609 codec->hw_write(codec->control_data, data, 2); 609 codec->hw_write(codec->control_data, data, 2);
610 } 610 }
611 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 611 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
612 wm8974_set_bias_level(codec, codec->suspend_bias_level); 612
613 return 0; 613 return 0;
614} 614}
615 615
@@ -677,7 +677,7 @@ static __devinit int wm8974_register(struct wm8974_priv *wm8974)
677 INIT_LIST_HEAD(&codec->dapm_widgets); 677 INIT_LIST_HEAD(&codec->dapm_widgets);
678 INIT_LIST_HEAD(&codec->dapm_paths); 678 INIT_LIST_HEAD(&codec->dapm_paths);
679 679
680 codec->private_data = wm8974; 680 snd_soc_codec_set_drvdata(codec, wm8974);
681 codec->name = "WM8974"; 681 codec->name = "WM8974";
682 codec->owner = THIS_MODULE; 682 codec->owner = THIS_MODULE;
683 codec->bias_level = SND_SOC_BIAS_OFF; 683 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 526f56b09066..51d5f433215c 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -439,7 +439,7 @@ static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
439 */ 439 */
440static int wm8978_configure_pll(struct snd_soc_codec *codec) 440static int wm8978_configure_pll(struct snd_soc_codec *codec)
441{ 441{
442 struct wm8978_priv *wm8978 = codec->private_data; 442 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
443 struct wm8978_pll_div pll_div; 443 struct wm8978_pll_div pll_div;
444 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk, 444 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
445 f_256fs = wm8978->f_256fs; 445 f_256fs = wm8978->f_256fs;
@@ -535,7 +535,7 @@ static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
535 int div_id, int div) 535 int div_id, int div)
536{ 536{
537 struct snd_soc_codec *codec = codec_dai->codec; 537 struct snd_soc_codec *codec = codec_dai->codec;
538 struct wm8978_priv *wm8978 = codec->private_data; 538 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
539 int ret = 0; 539 int ret = 0;
540 540
541 switch (div_id) { 541 switch (div_id) {
@@ -580,7 +580,7 @@ static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
580 unsigned int freq, int dir) 580 unsigned int freq, int dir)
581{ 581{
582 struct snd_soc_codec *codec = codec_dai->codec; 582 struct snd_soc_codec *codec = codec_dai->codec;
583 struct wm8978_priv *wm8978 = codec->private_data; 583 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
584 int ret = 0; 584 int ret = 0;
585 585
586 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq); 586 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
@@ -692,7 +692,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
692 struct snd_soc_pcm_runtime *rtd = substream->private_data; 692 struct snd_soc_pcm_runtime *rtd = substream->private_data;
693 struct snd_soc_device *socdev = rtd->socdev; 693 struct snd_soc_device *socdev = rtd->socdev;
694 struct snd_soc_codec *codec = socdev->card->codec; 694 struct snd_soc_codec *codec = socdev->card->codec;
695 struct wm8978_priv *wm8978 = codec->private_data; 695 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
696 /* Word length mask = 0x60 */ 696 /* Word length mask = 0x60 */
697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60; 697 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
698 /* Sampling rate mask = 0xe (for filters) */ 698 /* Sampling rate mask = 0xe (for filters) */
@@ -912,7 +912,7 @@ static int wm8978_resume(struct platform_device *pdev)
912{ 912{
913 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 913 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
914 struct snd_soc_codec *codec = socdev->card->codec; 914 struct snd_soc_codec *codec = socdev->card->codec;
915 struct wm8978_priv *wm8978 = codec->private_data; 915 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
916 int i; 916 int i;
917 u16 *cache = codec->reg_cache; 917 u16 *cache = codec->reg_cache;
918 918
@@ -1020,7 +1020,7 @@ static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1020 INIT_LIST_HEAD(&codec->dapm_widgets); 1020 INIT_LIST_HEAD(&codec->dapm_widgets);
1021 INIT_LIST_HEAD(&codec->dapm_paths); 1021 INIT_LIST_HEAD(&codec->dapm_paths);
1022 1022
1023 codec->private_data = wm8978; 1023 snd_soc_codec_set_drvdata(codec, wm8978);
1024 codec->name = "WM8978"; 1024 codec->name = "WM8978";
1025 codec->owner = THIS_MODULE; 1025 codec->owner = THIS_MODULE;
1026 codec->bias_level = SND_SOC_BIAS_OFF; 1026 codec->bias_level = SND_SOC_BIAS_OFF;
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index bb18c3ecfeb9..0417dae32e6f 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -495,7 +495,7 @@ static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
495 int clk_id, unsigned int freq, int dir) 495 int clk_id, unsigned int freq, int dir)
496{ 496{
497 struct snd_soc_codec *codec = codec_dai->codec; 497 struct snd_soc_codec *codec = codec_dai->codec;
498 struct wm8988_priv *wm8988 = codec->private_data; 498 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
499 499
500 switch (freq) { 500 switch (freq) {
501 case 11289600: 501 case 11289600:
@@ -585,7 +585,7 @@ static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
585 struct snd_soc_dai *dai) 585 struct snd_soc_dai *dai)
586{ 586{
587 struct snd_soc_codec *codec = dai->codec; 587 struct snd_soc_codec *codec = dai->codec;
588 struct wm8988_priv *wm8988 = codec->private_data; 588 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
589 589
590 /* The set of sample rates that can be supported depends on the 590 /* The set of sample rates that can be supported depends on the
591 * MCLK supplied to the CODEC - enforce this. 591 * MCLK supplied to the CODEC - enforce this.
@@ -610,7 +610,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
610 struct snd_soc_pcm_runtime *rtd = substream->private_data; 610 struct snd_soc_pcm_runtime *rtd = substream->private_data;
611 struct snd_soc_device *socdev = rtd->socdev; 611 struct snd_soc_device *socdev = rtd->socdev;
612 struct snd_soc_codec *codec = socdev->card->codec; 612 struct snd_soc_codec *codec = socdev->card->codec;
613 struct wm8988_priv *wm8988 = codec->private_data; 613 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
614 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3; 614 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
615 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180; 615 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
616 int coeff; 616 int coeff;
@@ -833,7 +833,7 @@ static int wm8988_register(struct wm8988_priv *wm8988,
833 INIT_LIST_HEAD(&codec->dapm_widgets); 833 INIT_LIST_HEAD(&codec->dapm_widgets);
834 INIT_LIST_HEAD(&codec->dapm_paths); 834 INIT_LIST_HEAD(&codec->dapm_paths);
835 835
836 codec->private_data = wm8988; 836 snd_soc_codec_set_drvdata(codec, wm8988);
837 codec->name = "WM8988"; 837 codec->name = "WM8988";
838 codec->owner = THIS_MODULE; 838 codec->owner = THIS_MODULE;
839 codec->dai = &wm8988_dai; 839 codec->dai = &wm8988_dai;
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 831f4730bfd5..7b536d923ea9 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1012,7 +1012,7 @@ static int wm8990_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1012 int clk_id, unsigned int freq, int dir) 1012 int clk_id, unsigned int freq, int dir)
1013{ 1013{
1014 struct snd_soc_codec *codec = codec_dai->codec; 1014 struct snd_soc_codec *codec = codec_dai->codec;
1015 struct wm8990_priv *wm8990 = codec->private_data; 1015 struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec);
1016 1016
1017 wm8990->sysclk = freq; 1017 wm8990->sysclk = freq;
1018 return 0; 1018 return 0;
@@ -1524,7 +1524,7 @@ static int wm8990_probe(struct platform_device *pdev)
1524 return -ENOMEM; 1524 return -ENOMEM;
1525 } 1525 }
1526 1526
1527 codec->private_data = wm8990; 1527 snd_soc_codec_set_drvdata(codec, wm8990);
1528 socdev->card->codec = codec; 1528 socdev->card->codec = codec;
1529 mutex_init(&codec->mutex); 1529 mutex_init(&codec->mutex);
1530 INIT_LIST_HEAD(&codec->dapm_widgets); 1530 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -1541,7 +1541,7 @@ static int wm8990_probe(struct platform_device *pdev)
1541#endif 1541#endif
1542 1542
1543 if (ret != 0) { 1543 if (ret != 0) {
1544 kfree(codec->private_data); 1544 kfree(snd_soc_codec_get_drvdata(codec));
1545 kfree(codec); 1545 kfree(codec);
1546 } 1546 }
1547 return ret; 1547 return ret;
@@ -1561,7 +1561,7 @@ static int wm8990_remove(struct platform_device *pdev)
1561 i2c_unregister_device(codec->control_data); 1561 i2c_unregister_device(codec->control_data);
1562 i2c_del_driver(&wm8990_i2c_driver); 1562 i2c_del_driver(&wm8990_i2c_driver);
1563#endif 1563#endif
1564 kfree(codec->private_data); 1564 kfree(snd_soc_codec_get_drvdata(codec));
1565 kfree(codec); 1565 kfree(codec);
1566 1566
1567 return 0; 1567 return 0;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 03e8b1a6a56c..d8d300c6175f 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -371,7 +371,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
371 unsigned int Fref, unsigned int Fout) 371 unsigned int Fref, unsigned int Fout)
372{ 372{
373 struct snd_soc_codec *codec = dai->codec; 373 struct snd_soc_codec *codec = dai->codec;
374 struct wm8993_priv *wm8993 = codec->private_data; 374 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
375 u16 reg1, reg4, reg5; 375 u16 reg1, reg4, reg5;
376 struct _fll_div fll_div; 376 struct _fll_div fll_div;
377 int ret; 377 int ret;
@@ -458,7 +458,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
458 458
459static int configure_clock(struct snd_soc_codec *codec) 459static int configure_clock(struct snd_soc_codec *codec)
460{ 460{
461 struct wm8993_priv *wm8993 = codec->private_data; 461 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
462 unsigned int reg; 462 unsigned int reg;
463 463
464 /* This should be done on init() for bypass paths */ 464 /* This should be done on init() for bypass paths */
@@ -717,7 +717,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
717{ 717{
718 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 718 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
719 struct snd_soc_codec *codec = widget->codec; 719 struct snd_soc_codec *codec = widget->codec;
720 struct wm8993_priv *wm8993 = codec->private_data; 720 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
721 int ret; 721 int ret;
722 722
723 /* Turn it off if we're using the main output mixer */ 723 /* Turn it off if we're using the main output mixer */
@@ -949,7 +949,7 @@ static void wm8993_cache_restore(struct snd_soc_codec *codec)
949static int wm8993_set_bias_level(struct snd_soc_codec *codec, 949static int wm8993_set_bias_level(struct snd_soc_codec *codec,
950 enum snd_soc_bias_level level) 950 enum snd_soc_bias_level level)
951{ 951{
952 struct wm8993_priv *wm8993 = codec->private_data; 952 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
953 int ret; 953 int ret;
954 954
955 switch (level) { 955 switch (level) {
@@ -1047,7 +1047,7 @@ static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
1047 int clk_id, unsigned int freq, int dir) 1047 int clk_id, unsigned int freq, int dir)
1048{ 1048{
1049 struct snd_soc_codec *codec = codec_dai->codec; 1049 struct snd_soc_codec *codec = codec_dai->codec;
1050 struct wm8993_priv *wm8993 = codec->private_data; 1050 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1051 1051
1052 switch (clk_id) { 1052 switch (clk_id) {
1053 case WM8993_SYSCLK_MCLK: 1053 case WM8993_SYSCLK_MCLK:
@@ -1067,7 +1067,7 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1067 unsigned int fmt) 1067 unsigned int fmt)
1068{ 1068{
1069 struct snd_soc_codec *codec = dai->codec; 1069 struct snd_soc_codec *codec = dai->codec;
1070 struct wm8993_priv *wm8993 = codec->private_data; 1070 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1071 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1); 1071 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1072 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4); 1072 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1073 1073
@@ -1163,7 +1163,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1163 struct snd_soc_dai *dai) 1163 struct snd_soc_dai *dai)
1164{ 1164{
1165 struct snd_soc_codec *codec = dai->codec; 1165 struct snd_soc_codec *codec = dai->codec;
1166 struct wm8993_priv *wm8993 = codec->private_data; 1166 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1167 int ret, i, best, best_val, cur_val; 1167 int ret, i, best, best_val, cur_val;
1168 unsigned int clocking1, clocking3, aif1, aif4; 1168 unsigned int clocking1, clocking3, aif1, aif4;
1169 1169
@@ -1328,7 +1328,7 @@ static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1328 unsigned int rx_mask, int slots, int slot_width) 1328 unsigned int rx_mask, int slots, int slot_width)
1329{ 1329{
1330 struct snd_soc_codec *codec = dai->codec; 1330 struct snd_soc_codec *codec = dai->codec;
1331 struct wm8993_priv *wm8993 = codec->private_data; 1331 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1332 int aif1 = 0; 1332 int aif1 = 0;
1333 int aif2 = 0; 1333 int aif2 = 0;
1334 1334
@@ -1431,7 +1431,7 @@ static int wm8993_probe(struct platform_device *pdev)
1431 1431
1432 socdev->card->codec = wm8993_codec; 1432 socdev->card->codec = wm8993_codec;
1433 codec = wm8993_codec; 1433 codec = wm8993_codec;
1434 wm8993 = codec->private_data; 1434 wm8993 = snd_soc_codec_get_drvdata(codec);
1435 1435
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1437 if (ret < 0) { 1437 if (ret < 0) {
@@ -1478,7 +1478,7 @@ static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1478{ 1478{
1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1480 struct snd_soc_codec *codec = socdev->card->codec; 1480 struct snd_soc_codec *codec = socdev->card->codec;
1481 struct wm8993_priv *wm8993 = codec->private_data; 1481 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1482 int fll_fout = wm8993->fll_fout; 1482 int fll_fout = wm8993->fll_fout;
1483 int fll_fref = wm8993->fll_fref; 1483 int fll_fref = wm8993->fll_fref;
1484 int ret; 1484 int ret;
@@ -1502,7 +1502,7 @@ static int wm8993_resume(struct platform_device *pdev)
1502{ 1502{
1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1504 struct snd_soc_codec *codec = socdev->card->codec; 1504 struct snd_soc_codec *codec = socdev->card->codec;
1505 struct wm8993_priv *wm8993 = codec->private_data; 1505 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1506 int ret; 1506 int ret;
1507 1507
1508 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1508 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1571,7 +1571,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1571 codec->set_bias_level = wm8993_set_bias_level; 1571 codec->set_bias_level = wm8993_set_bias_level;
1572 codec->dai = &wm8993_dai; 1572 codec->dai = &wm8993_dai;
1573 codec->num_dai = 1; 1573 codec->num_dai = 1;
1574 codec->private_data = wm8993; 1574 snd_soc_codec_set_drvdata(codec, wm8993);
1575 1575
1576 wm8993->hubs_data.hp_startup_mode = 1; 1576 wm8993->hubs_data.hp_startup_mode = 1;
1577 wm8993->hubs_data.dcs_codes = -2; 1577 wm8993->hubs_data.dcs_codes = -2;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 9da0724cd47a..e84a1177f350 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -62,6 +62,12 @@ static int wm8994_retune_mobile_base[] = {
62 62
63#define WM8994_REG_CACHE_SIZE 0x621 63#define WM8994_REG_CACHE_SIZE 0x621
64 64
65struct wm8994_micdet {
66 struct snd_soc_jack *jack;
67 int det;
68 int shrt;
69};
70
65/* codec private data */ 71/* codec private data */
66struct wm8994_priv { 72struct wm8994_priv {
67 struct wm_hubs_data hubs; 73 struct wm_hubs_data hubs;
@@ -87,6 +93,8 @@ struct wm8994_priv {
87 int retune_mobile_cfg[WM8994_NUM_EQ]; 93 int retune_mobile_cfg[WM8994_NUM_EQ];
88 struct soc_enum retune_mobile_enum; 94 struct soc_enum retune_mobile_enum;
89 95
96 struct wm8994_micdet micdet[2];
97
90 struct wm8994_pdata *pdata; 98 struct wm8994_pdata *pdata;
91}; 99};
92 100
@@ -1696,13 +1704,15 @@ static int wm8994_volatile(unsigned int reg)
1696static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, 1704static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1697 unsigned int value) 1705 unsigned int value)
1698{ 1706{
1699 struct wm8994_priv *wm8994 = codec->private_data; 1707 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1700 1708
1701 BUG_ON(reg > WM8994_MAX_REGISTER); 1709 BUG_ON(reg > WM8994_MAX_REGISTER);
1702 1710
1703 if (!wm8994_volatile(reg)) 1711 if (!wm8994_volatile(reg))
1704 wm8994->reg_cache[reg] = value; 1712 wm8994->reg_cache[reg] = value;
1705 1713
1714 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
1715
1706 return wm8994_reg_write(codec->control_data, reg, value); 1716 return wm8994_reg_write(codec->control_data, reg, value);
1707} 1717}
1708 1718
@@ -1721,7 +1731,7 @@ static unsigned int wm8994_read(struct snd_soc_codec *codec,
1721 1731
1722static int configure_aif_clock(struct snd_soc_codec *codec, int aif) 1732static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1723{ 1733{
1724 struct wm8994_priv *wm8994 = codec->private_data; 1734 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1725 int rate; 1735 int rate;
1726 int reg1 = 0; 1736 int reg1 = 0;
1727 int offset; 1737 int offset;
@@ -1762,6 +1772,11 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1762 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n", 1772 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
1763 aif + 1, rate); 1773 aif + 1, rate);
1764 } 1774 }
1775
1776 if (rate && rate < 3000000)
1777 dev_warn(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
1778 aif + 1, rate);
1779
1765 wm8994->aifclk[aif] = rate; 1780 wm8994->aifclk[aif] = rate;
1766 1781
1767 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset, 1782 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
@@ -1773,7 +1788,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1773 1788
1774static int configure_clock(struct snd_soc_codec *codec) 1789static int configure_clock(struct snd_soc_codec *codec)
1775{ 1790{
1776 struct wm8994_priv *wm8994 = codec->private_data; 1791 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1777 int old, new; 1792 int old, new;
1778 1793
1779 /* Bring up the AIF clocks first */ 1794 /* Bring up the AIF clocks first */
@@ -1870,7 +1885,7 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1870 1885
1871static void wm8994_set_drc(struct snd_soc_codec *codec, int drc) 1886static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1872{ 1887{
1873 struct wm8994_priv *wm8994 = codec->private_data; 1888 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1874 struct wm8994_pdata *pdata = wm8994->pdata; 1889 struct wm8994_pdata *pdata = wm8994->pdata;
1875 int base = wm8994_drc_base[drc]; 1890 int base = wm8994_drc_base[drc];
1876 int cfg = wm8994->drc_cfg[drc]; 1891 int cfg = wm8994->drc_cfg[drc];
@@ -1906,7 +1921,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1906 struct snd_ctl_elem_value *ucontrol) 1921 struct snd_ctl_elem_value *ucontrol)
1907{ 1922{
1908 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1923 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1909 struct wm8994_priv *wm8994 = codec->private_data; 1924 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1910 struct wm8994_pdata *pdata = wm8994->pdata; 1925 struct wm8994_pdata *pdata = wm8994->pdata;
1911 int drc = wm8994_get_drc(kcontrol->id.name); 1926 int drc = wm8994_get_drc(kcontrol->id.name);
1912 int value = ucontrol->value.integer.value[0]; 1927 int value = ucontrol->value.integer.value[0];
@@ -1928,7 +1943,7 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1928 struct snd_ctl_elem_value *ucontrol) 1943 struct snd_ctl_elem_value *ucontrol)
1929{ 1944{
1930 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1945 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1931 struct wm8994_priv *wm8994 = codec->private_data; 1946 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1932 int drc = wm8994_get_drc(kcontrol->id.name); 1947 int drc = wm8994_get_drc(kcontrol->id.name);
1933 1948
1934 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc]; 1949 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
@@ -1938,7 +1953,7 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1938 1953
1939static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block) 1954static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
1940{ 1955{
1941 struct wm8994_priv *wm8994 = codec->private_data; 1956 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
1942 struct wm8994_pdata *pdata = wm8994->pdata; 1957 struct wm8994_pdata *pdata = wm8994->pdata;
1943 int base = wm8994_retune_mobile_base[block]; 1958 int base = wm8994_retune_mobile_base[block];
1944 int iface, best, best_val, save, i, cfg; 1959 int iface, best, best_val, save, i, cfg;
@@ -2009,7 +2024,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2009 struct snd_ctl_elem_value *ucontrol) 2024 struct snd_ctl_elem_value *ucontrol)
2010{ 2025{
2011 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2026 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2012 struct wm8994_priv *wm8994 = codec->private_data; 2027 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2013 struct wm8994_pdata *pdata = wm8994->pdata; 2028 struct wm8994_pdata *pdata = wm8994->pdata;
2014 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 2029 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2015 int value = ucontrol->value.integer.value[0]; 2030 int value = ucontrol->value.integer.value[0];
@@ -2031,7 +2046,7 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_value *ucontrol) 2046 struct snd_ctl_elem_value *ucontrol)
2032{ 2047{
2033 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2048 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2034 struct wm8994_priv *wm8994 = codec->private_data; 2049 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2035 int block = wm8994_get_retune_mobile_block(kcontrol->id.name); 2050 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2036 2051
2037 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block]; 2052 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
@@ -2182,13 +2197,13 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
2182 /* Only support direct DAC->headphone paths */ 2197 /* Only support direct DAC->headphone paths */
2183 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1); 2198 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
2184 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) { 2199 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
2185 dev_dbg(codec->dev, "HPL connected to output mixer\n"); 2200 dev_vdbg(codec->dev, "HPL connected to output mixer\n");
2186 enable = 0; 2201 enable = 0;
2187 } 2202 }
2188 2203
2189 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2); 2204 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
2190 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) { 2205 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
2191 dev_dbg(codec->dev, "HPR connected to output mixer\n"); 2206 dev_vdbg(codec->dev, "HPR connected to output mixer\n");
2192 enable = 0; 2207 enable = 0;
2193 } 2208 }
2194 2209
@@ -2196,26 +2211,26 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
2196 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); 2211 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
2197 switch (reg) { 2212 switch (reg) {
2198 case WM8994_AIF2DACL_TO_DAC1L: 2213 case WM8994_AIF2DACL_TO_DAC1L:
2199 dev_dbg(codec->dev, "Class W source AIF2DAC\n"); 2214 dev_vdbg(codec->dev, "Class W source AIF2DAC\n");
2200 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT; 2215 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2201 break; 2216 break;
2202 case WM8994_AIF1DAC2L_TO_DAC1L: 2217 case WM8994_AIF1DAC2L_TO_DAC1L:
2203 dev_dbg(codec->dev, "Class W source AIF1DAC2\n"); 2218 dev_vdbg(codec->dev, "Class W source AIF1DAC2\n");
2204 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT; 2219 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2205 break; 2220 break;
2206 case WM8994_AIF1DAC1L_TO_DAC1L: 2221 case WM8994_AIF1DAC1L_TO_DAC1L:
2207 dev_dbg(codec->dev, "Class W source AIF1DAC1\n"); 2222 dev_vdbg(codec->dev, "Class W source AIF1DAC1\n");
2208 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT; 2223 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2209 break; 2224 break;
2210 default: 2225 default:
2211 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg); 2226 dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg);
2212 enable = 0; 2227 enable = 0;
2213 break; 2228 break;
2214 } 2229 }
2215 2230
2216 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING); 2231 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
2217 if (reg_r != reg) { 2232 if (reg_r != reg) {
2218 dev_dbg(codec->dev, "Left and right DAC mixers different\n"); 2233 dev_vdbg(codec->dev, "Left and right DAC mixers different\n");
2219 enable = 0; 2234 enable = 0;
2220 } 2235 }
2221 2236
@@ -2777,9 +2792,18 @@ static int wm8994_get_fll_config(struct fll_div *fll,
2777 2792
2778 if (freq_in > 1000000) { 2793 if (freq_in > 1000000) {
2779 fll->fll_fratio = 0; 2794 fll->fll_fratio = 0;
2780 } else { 2795 } else if (freq_in > 256000) {
2796 fll->fll_fratio = 1;
2797 freq_in *= 2;
2798 } else if (freq_in > 128000) {
2799 fll->fll_fratio = 2;
2800 freq_in *= 4;
2801 } else if (freq_in > 64000) {
2781 fll->fll_fratio = 3; 2802 fll->fll_fratio = 3;
2782 freq_in *= 8; 2803 freq_in *= 8;
2804 } else {
2805 fll->fll_fratio = 4;
2806 freq_in *= 16;
2783 } 2807 }
2784 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in); 2808 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
2785 2809
@@ -2812,7 +2836,7 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2812 unsigned int freq_in, unsigned int freq_out) 2836 unsigned int freq_in, unsigned int freq_out)
2813{ 2837{
2814 struct snd_soc_codec *codec = dai->codec; 2838 struct snd_soc_codec *codec = dai->codec;
2815 struct wm8994_priv *wm8994 = codec->private_data; 2839 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2816 int reg_offset, ret; 2840 int reg_offset, ret;
2817 struct fll_div fll; 2841 struct fll_div fll;
2818 u16 reg, aif1, aif2; 2842 u16 reg, aif1, aif2;
@@ -2836,6 +2860,21 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2836 return -EINVAL; 2860 return -EINVAL;
2837 } 2861 }
2838 2862
2863 switch (src) {
2864 case 0:
2865 /* Allow no source specification when stopping */
2866 if (freq_out)
2867 return -EINVAL;
2868 break;
2869 case WM8994_FLL_SRC_MCLK1:
2870 case WM8994_FLL_SRC_MCLK2:
2871 case WM8994_FLL_SRC_LRCLK:
2872 case WM8994_FLL_SRC_BCLK:
2873 break;
2874 default:
2875 return -EINVAL;
2876 }
2877
2839 /* Are we changing anything? */ 2878 /* Are we changing anything? */
2840 if (wm8994->fll[id].src == src && 2879 if (wm8994->fll[id].src == src &&
2841 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out) 2880 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
@@ -2876,8 +2915,10 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2876 fll.n << WM8994_FLL1_N_SHIFT); 2915 fll.n << WM8994_FLL1_N_SHIFT);
2877 2916
2878 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, 2917 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2879 WM8994_FLL1_REFCLK_DIV_MASK, 2918 WM8994_FLL1_REFCLK_DIV_MASK |
2880 fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT); 2919 WM8994_FLL1_REFCLK_SRC_MASK,
2920 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
2921 (src - 1));
2881 2922
2882 /* Enable (with fractional mode if required) */ 2923 /* Enable (with fractional mode if required) */
2883 if (freq_out) { 2924 if (freq_out) {
@@ -2892,6 +2933,7 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2892 2933
2893 wm8994->fll[id].in = freq_in; 2934 wm8994->fll[id].in = freq_in;
2894 wm8994->fll[id].out = freq_out; 2935 wm8994->fll[id].out = freq_out;
2936 wm8994->fll[id].src = src;
2895 2937
2896 /* Enable any gated AIF clocks */ 2938 /* Enable any gated AIF clocks */
2897 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, 2939 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
@@ -2908,7 +2950,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2908 int clk_id, unsigned int freq, int dir) 2950 int clk_id, unsigned int freq, int dir)
2909{ 2951{
2910 struct snd_soc_codec *codec = dai->codec; 2952 struct snd_soc_codec *codec = dai->codec;
2911 struct wm8994_priv *wm8994 = codec->private_data; 2953 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2912 2954
2913 switch (dai->id) { 2955 switch (dai->id) {
2914 case 1: 2956 case 1:
@@ -3174,7 +3216,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3174 struct snd_soc_dai *dai) 3216 struct snd_soc_dai *dai)
3175{ 3217{
3176 struct snd_soc_codec *codec = dai->codec; 3218 struct snd_soc_codec *codec = dai->codec;
3177 struct wm8994_priv *wm8994 = codec->private_data; 3219 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3178 int aif1_reg; 3220 int aif1_reg;
3179 int bclk_reg; 3221 int bclk_reg;
3180 int lrclk_reg; 3222 int lrclk_reg;
@@ -3338,6 +3380,36 @@ static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3338 return 0; 3380 return 0;
3339} 3381}
3340 3382
3383static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
3384{
3385 struct snd_soc_codec *codec = codec_dai->codec;
3386 int reg, val, mask;
3387
3388 switch (codec_dai->id) {
3389 case 1:
3390 reg = WM8994_AIF1_MASTER_SLAVE;
3391 mask = WM8994_AIF1_TRI;
3392 break;
3393 case 2:
3394 reg = WM8994_AIF2_MASTER_SLAVE;
3395 mask = WM8994_AIF2_TRI;
3396 break;
3397 case 3:
3398 reg = WM8994_POWER_MANAGEMENT_6;
3399 mask = WM8994_AIF3_TRI;
3400 break;
3401 default:
3402 return -EINVAL;
3403 }
3404
3405 if (tristate)
3406 val = mask;
3407 else
3408 val = 0;
3409
3410 return snd_soc_update_bits(codec, reg, mask, reg);
3411}
3412
3341#define WM8994_RATES SNDRV_PCM_RATE_8000_96000 3413#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
3342 3414
3343#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 3415#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
@@ -3349,6 +3421,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
3349 .hw_params = wm8994_hw_params, 3421 .hw_params = wm8994_hw_params,
3350 .digital_mute = wm8994_aif_mute, 3422 .digital_mute = wm8994_aif_mute,
3351 .set_pll = wm8994_set_fll, 3423 .set_pll = wm8994_set_fll,
3424 .set_tristate = wm8994_set_tristate,
3352}; 3425};
3353 3426
3354static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { 3427static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
@@ -3357,6 +3430,11 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3357 .hw_params = wm8994_hw_params, 3430 .hw_params = wm8994_hw_params,
3358 .digital_mute = wm8994_aif_mute, 3431 .digital_mute = wm8994_aif_mute,
3359 .set_pll = wm8994_set_fll, 3432 .set_pll = wm8994_set_fll,
3433 .set_tristate = wm8994_set_tristate,
3434};
3435
3436static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
3437 .set_tristate = wm8994_set_tristate,
3360}; 3438};
3361 3439
3362struct snd_soc_dai wm8994_dai[] = { 3440struct snd_soc_dai wm8994_dai[] = {
@@ -3400,6 +3478,7 @@ struct snd_soc_dai wm8994_dai[] = {
3400 }, 3478 },
3401 { 3479 {
3402 .name = "WM8994 AIF3", 3480 .name = "WM8994 AIF3",
3481 .id = 3,
3403 .playback = { 3482 .playback = {
3404 .stream_name = "AIF3 Playback", 3483 .stream_name = "AIF3 Playback",
3405 .channels_min = 2, 3484 .channels_min = 2,
@@ -3414,6 +3493,7 @@ struct snd_soc_dai wm8994_dai[] = {
3414 .rates = WM8994_RATES, 3493 .rates = WM8994_RATES,
3415 .formats = WM8994_FORMATS, 3494 .formats = WM8994_FORMATS,
3416 }, 3495 },
3496 .ops = &wm8994_aif3_dai_ops,
3417 } 3497 }
3418}; 3498};
3419EXPORT_SYMBOL_GPL(wm8994_dai); 3499EXPORT_SYMBOL_GPL(wm8994_dai);
@@ -3423,7 +3503,7 @@ static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3423{ 3503{
3424 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 3504 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3425 struct snd_soc_codec *codec = socdev->card->codec; 3505 struct snd_soc_codec *codec = socdev->card->codec;
3426 struct wm8994_priv *wm8994 = codec->private_data; 3506 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3427 int i, ret; 3507 int i, ret;
3428 3508
3429 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 3509 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
@@ -3444,7 +3524,7 @@ static int wm8994_resume(struct platform_device *pdev)
3444{ 3524{
3445 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 3525 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3446 struct snd_soc_codec *codec = socdev->card->codec; 3526 struct snd_soc_codec *codec = socdev->card->codec;
3447 struct wm8994_priv *wm8994 = codec->private_data; 3527 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3448 u16 *reg_cache = codec->reg_cache; 3528 u16 *reg_cache = codec->reg_cache;
3449 int i, ret; 3529 int i, ret;
3450 3530
@@ -3469,6 +3549,9 @@ static int wm8994_resume(struct platform_device *pdev)
3469 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 3549 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3470 3550
3471 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 3551 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3552 if (!wm8994->fll_suspend[i].out)
3553 continue;
3554
3472 ret = wm8994_set_fll(&codec->dai[0], i + 1, 3555 ret = wm8994_set_fll(&codec->dai[0], i + 1,
3473 wm8994->fll_suspend[i].src, 3556 wm8994->fll_suspend[i].src,
3474 wm8994->fll_suspend[i].in, 3557 wm8994->fll_suspend[i].in,
@@ -3639,7 +3722,7 @@ static int wm8994_probe(struct platform_device *pdev)
3639 return ret; 3722 return ret;
3640 } 3723 }
3641 3724
3642 wm8994_handle_pdata(codec->private_data); 3725 wm8994_handle_pdata(snd_soc_codec_get_drvdata(codec));
3643 3726
3644 wm_hubs_add_analogue_controls(codec); 3727 wm_hubs_add_analogue_controls(codec);
3645 snd_soc_add_controls(codec, wm8994_snd_controls, 3728 snd_soc_add_controls(codec, wm8994_snd_controls,
@@ -3670,6 +3753,96 @@ struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3670}; 3753};
3671EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994); 3754EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3672 3755
3756/**
3757 * wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ
3758 *
3759 * @codec: WM8994 codec
3760 * @jack: jack to report detection events on
3761 * @micbias: microphone bias to detect on
3762 * @det: value to report for presence detection
3763 * @shrt: value to report for short detection
3764 *
3765 * Enable microphone detection via IRQ on the WM8994. If GPIOs are
3766 * being used to bring out signals to the processor then only platform
3767 * data configuration is needed for WM8903 and processor GPIOs should
3768 * be configured using snd_soc_jack_add_gpios() instead.
3769 *
3770 * Configuration of detection levels is available via the micbias1_lvl
3771 * and micbias2_lvl platform data members.
3772 */
3773int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3774 int micbias, int det, int shrt)
3775{
3776 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3777 struct wm8994_micdet *micdet;
3778 int reg;
3779
3780 switch (micbias) {
3781 case 1:
3782 micdet = &wm8994->micdet[0];
3783 break;
3784 case 2:
3785 micdet = &wm8994->micdet[1];
3786 break;
3787 default:
3788 return -EINVAL;
3789 }
3790
3791 dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n",
3792 micbias, det, shrt);
3793
3794 /* Store the configuration */
3795 micdet->jack = jack;
3796 micdet->det = det;
3797 micdet->shrt = shrt;
3798
3799 /* If either of the jacks is set up then enable detection */
3800 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
3801 reg = WM8994_MICD_ENA;
3802 else
3803 reg = 0;
3804
3805 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
3806
3807 return 0;
3808}
3809EXPORT_SYMBOL_GPL(wm8994_mic_detect);
3810
3811static irqreturn_t wm8994_mic_irq(int irq, void *data)
3812{
3813 struct wm8994_priv *priv = data;
3814 struct snd_soc_codec *codec = &priv->codec;
3815 int reg;
3816 int report;
3817
3818 reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2);
3819 if (reg < 0) {
3820 dev_err(codec->dev, "Failed to read microphone status: %d\n",
3821 reg);
3822 return IRQ_HANDLED;
3823 }
3824
3825 dev_dbg(codec->dev, "Microphone status: %x\n", reg);
3826
3827 report = 0;
3828 if (reg & WM8994_MIC1_DET_STS)
3829 report |= priv->micdet[0].det;
3830 if (reg & WM8994_MIC1_SHRT_STS)
3831 report |= priv->micdet[0].shrt;
3832 snd_soc_jack_report(priv->micdet[0].jack, report,
3833 priv->micdet[0].det | priv->micdet[0].shrt);
3834
3835 report = 0;
3836 if (reg & WM8994_MIC2_DET_STS)
3837 report |= priv->micdet[1].det;
3838 if (reg & WM8994_MIC2_SHRT_STS)
3839 report |= priv->micdet[1].shrt;
3840 snd_soc_jack_report(priv->micdet[1].jack, report,
3841 priv->micdet[1].det | priv->micdet[1].shrt);
3842
3843 return IRQ_HANDLED;
3844}
3845
3673static int wm8994_codec_probe(struct platform_device *pdev) 3846static int wm8994_codec_probe(struct platform_device *pdev)
3674{ 3847{
3675 int ret; 3848 int ret;
@@ -3695,7 +3868,7 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3695 INIT_LIST_HEAD(&codec->dapm_widgets); 3868 INIT_LIST_HEAD(&codec->dapm_widgets);
3696 INIT_LIST_HEAD(&codec->dapm_paths); 3869 INIT_LIST_HEAD(&codec->dapm_paths);
3697 3870
3698 codec->private_data = wm8994; 3871 snd_soc_codec_set_drvdata(codec, wm8994);
3699 codec->control_data = dev_get_drvdata(pdev->dev.parent); 3872 codec->control_data = dev_get_drvdata(pdev->dev.parent);
3700 codec->name = "WM8994"; 3873 codec->name = "WM8994";
3701 codec->owner = THIS_MODULE; 3874 codec->owner = THIS_MODULE;
@@ -3743,6 +3916,30 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3743 break; 3916 break;
3744 } 3917 }
3745 3918
3919 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
3920 wm8994_mic_irq, "Mic 1 detect", wm8994);
3921 if (ret != 0)
3922 dev_warn(&pdev->dev,
3923 "Failed to request Mic1 detect IRQ: %d\n", ret);
3924
3925 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
3926 wm8994_mic_irq, "Mic 1 short", wm8994);
3927 if (ret != 0)
3928 dev_warn(&pdev->dev,
3929 "Failed to request Mic1 short IRQ: %d\n", ret);
3930
3931 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
3932 wm8994_mic_irq, "Mic 2 detect", wm8994);
3933 if (ret != 0)
3934 dev_warn(&pdev->dev,
3935 "Failed to request Mic2 detect IRQ: %d\n", ret);
3936
3937 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
3938 wm8994_mic_irq, "Mic 2 short", wm8994);
3939 if (ret != 0)
3940 dev_warn(&pdev->dev,
3941 "Failed to request Mic2 short IRQ: %d\n", ret);
3942
3746 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3943 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3747 * configured on init - if a system wants to do this dynamically 3944 * configured on init - if a system wants to do this dynamically
3748 * at runtime we can deal with that then. 3945 * at runtime we can deal with that then.
@@ -3750,7 +3947,7 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3750 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1); 3947 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
3751 if (ret < 0) { 3948 if (ret < 0) {
3752 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret); 3949 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
3753 goto err; 3950 goto err_irq;
3754 } 3951 }
3755 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { 3952 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3756 wm8994->lrclk_shared[0] = 1; 3953 wm8994->lrclk_shared[0] = 1;
@@ -3762,7 +3959,7 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3762 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6); 3959 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
3763 if (ret < 0) { 3960 if (ret < 0) {
3764 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret); 3961 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
3765 goto err; 3962 goto err_irq;
3766 } 3963 }
3767 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { 3964 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3768 wm8994->lrclk_shared[1] = 1; 3965 wm8994->lrclk_shared[1] = 1;
@@ -3812,7 +4009,7 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3812 ret = snd_soc_register_codec(codec); 4009 ret = snd_soc_register_codec(codec);
3813 if (ret != 0) { 4010 if (ret != 0) {
3814 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 4011 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
3815 goto err; 4012 goto err_irq;
3816 } 4013 }
3817 4014
3818 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); 4015 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
@@ -3827,6 +4024,11 @@ static int wm8994_codec_probe(struct platform_device *pdev)
3827 4024
3828err_codec: 4025err_codec:
3829 snd_soc_unregister_codec(codec); 4026 snd_soc_unregister_codec(codec);
4027err_irq:
4028 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
4029 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
4030 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
4031 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
3830err: 4032err:
3831 kfree(wm8994); 4033 kfree(wm8994);
3832 return ret; 4034 return ret;
@@ -3840,6 +4042,10 @@ static int __devexit wm8994_codec_remove(struct platform_device *pdev)
3840 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 4042 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3841 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai)); 4043 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3842 snd_soc_unregister_codec(&wm8994->codec); 4044 snd_soc_unregister_codec(&wm8994->codec);
4045 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
4046 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
4047 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
4048 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
3843 kfree(wm8994); 4049 kfree(wm8994);
3844 wm8994_codec = NULL; 4050 wm8994_codec = NULL;
3845 4051
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index 0a5e1424dea0..7072dc539354 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -23,4 +23,12 @@ extern struct snd_soc_dai wm8994_dai[];
23#define WM8994_FLL1 1 23#define WM8994_FLL1 1
24#define WM8994_FLL2 2 24#define WM8994_FLL2 2
25 25
26#define WM8994_FLL_SRC_MCLK1 1
27#define WM8994_FLL_SRC_MCLK2 2
28#define WM8994_FLL_SRC_LRCLK 3
29#define WM8994_FLL_SRC_BCLK 4
30
31int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
32 int micbias, int det, int shrt);
33
26#endif 34#endif
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 3a184fcb702b..13186fb4dcb4 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -521,7 +521,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
521static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id, 521static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
522 unsigned int Fref, unsigned int Fout) 522 unsigned int Fref, unsigned int Fout)
523{ 523{
524 struct wm9081_priv *wm9081 = codec->private_data; 524 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
525 u16 reg1, reg4, reg5; 525 u16 reg1, reg4, reg5;
526 struct _fll_div fll_div; 526 struct _fll_div fll_div;
527 int ret; 527 int ret;
@@ -607,7 +607,7 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
607 607
608static int configure_clock(struct snd_soc_codec *codec) 608static int configure_clock(struct snd_soc_codec *codec)
609{ 609{
610 struct wm9081_priv *wm9081 = codec->private_data; 610 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
611 int new_sysclk, i, target; 611 int new_sysclk, i, target;
612 unsigned int reg; 612 unsigned int reg;
613 int ret = 0; 613 int ret = 0;
@@ -702,7 +702,7 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
702 struct snd_kcontrol *kcontrol, int event) 702 struct snd_kcontrol *kcontrol, int event)
703{ 703{
704 struct snd_soc_codec *codec = w->codec; 704 struct snd_soc_codec *codec = w->codec;
705 struct wm9081_priv *wm9081 = codec->private_data; 705 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
706 706
707 /* This should be done on init() for bypass paths */ 707 /* This should be done on init() for bypass paths */
708 switch (wm9081->sysclk_source) { 708 switch (wm9081->sysclk_source) {
@@ -873,7 +873,7 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
873 unsigned int fmt) 873 unsigned int fmt)
874{ 874{
875 struct snd_soc_codec *codec = dai->codec; 875 struct snd_soc_codec *codec = dai->codec;
876 struct wm9081_priv *wm9081 = codec->private_data; 876 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
877 unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2); 877 unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
878 878
879 aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV | 879 aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV |
@@ -965,7 +965,7 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
965 struct snd_soc_dai *dai) 965 struct snd_soc_dai *dai)
966{ 966{
967 struct snd_soc_codec *codec = dai->codec; 967 struct snd_soc_codec *codec = dai->codec;
968 struct wm9081_priv *wm9081 = codec->private_data; 968 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
969 int ret, i, best, best_val, cur_val; 969 int ret, i, best, best_val, cur_val;
970 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4; 970 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4;
971 971
@@ -1139,7 +1139,7 @@ static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai,
1139 int clk_id, unsigned int freq, int dir) 1139 int clk_id, unsigned int freq, int dir)
1140{ 1140{
1141 struct snd_soc_codec *codec = codec_dai->codec; 1141 struct snd_soc_codec *codec = codec_dai->codec;
1142 struct wm9081_priv *wm9081 = codec->private_data; 1142 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1143 1143
1144 switch (clk_id) { 1144 switch (clk_id) {
1145 case WM9081_SYSCLK_MCLK: 1145 case WM9081_SYSCLK_MCLK:
@@ -1159,7 +1159,7 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1159 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) 1159 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
1160{ 1160{
1161 struct snd_soc_codec *codec = dai->codec; 1161 struct snd_soc_codec *codec = dai->codec;
1162 struct wm9081_priv *wm9081 = codec->private_data; 1162 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1163 unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1); 1163 unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
1164 1164
1165 aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); 1165 aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK);
@@ -1242,7 +1242,7 @@ static int wm9081_probe(struct platform_device *pdev)
1242 1242
1243 socdev->card->codec = wm9081_codec; 1243 socdev->card->codec = wm9081_codec;
1244 codec = wm9081_codec; 1244 codec = wm9081_codec;
1245 wm9081 = codec->private_data; 1245 wm9081 = snd_soc_codec_get_drvdata(codec);
1246 1246
1247 /* register pcms */ 1247 /* register pcms */
1248 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1248 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -1339,7 +1339,7 @@ static int wm9081_register(struct wm9081_priv *wm9081,
1339 INIT_LIST_HEAD(&codec->dapm_widgets); 1339 INIT_LIST_HEAD(&codec->dapm_widgets);
1340 INIT_LIST_HEAD(&codec->dapm_paths); 1340 INIT_LIST_HEAD(&codec->dapm_paths);
1341 1341
1342 codec->private_data = wm9081; 1342 snd_soc_codec_set_drvdata(codec, wm9081);
1343 codec->name = "WM9081"; 1343 codec->name = "WM9081";
1344 codec->owner = THIS_MODULE; 1344 codec->owner = THIS_MODULE;
1345 codec->dai = &wm9081_dai; 1345 codec->dai = &wm9081_dai;
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
new file mode 100644
index 000000000000..1592250daec0
--- /dev/null
+++ b/sound/soc/codecs/wm9090.c
@@ -0,0 +1,773 @@
1/*
2 * ALSA SoC WM9090 driver
3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/device.h>
26#include <linux/i2c.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <sound/initval.h>
30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/tlv.h>
33#include <sound/wm9090.h>
34
35#include "wm9090.h"
36
37static struct snd_soc_codec *wm9090_codec;
38
39static const u16 wm9090_reg_defaults[] = {
40 0x9093, /* R0 - Software Reset */
41 0x0006, /* R1 - Power Management (1) */
42 0x6000, /* R2 - Power Management (2) */
43 0x0000, /* R3 - Power Management (3) */
44 0x0000, /* R4 */
45 0x0000, /* R5 */
46 0x01C0, /* R6 - Clocking 1 */
47 0x0000, /* R7 */
48 0x0000, /* R8 */
49 0x0000, /* R9 */
50 0x0000, /* R10 */
51 0x0000, /* R11 */
52 0x0000, /* R12 */
53 0x0000, /* R13 */
54 0x0000, /* R14 */
55 0x0000, /* R15 */
56 0x0000, /* R16 */
57 0x0000, /* R17 */
58 0x0000, /* R18 */
59 0x0000, /* R19 */
60 0x0000, /* R20 */
61 0x0000, /* R21 */
62 0x0003, /* R22 - IN1 Line Control */
63 0x0003, /* R23 - IN2 Line Control */
64 0x0083, /* R24 - IN1 Line Input A Volume */
65 0x0083, /* R25 - IN1 Line Input B Volume */
66 0x0083, /* R26 - IN2 Line Input A Volume */
67 0x0083, /* R27 - IN2 Line Input B Volume */
68 0x002D, /* R28 - Left Output Volume */
69 0x002D, /* R29 - Right Output Volume */
70 0x0000, /* R30 */
71 0x0000, /* R31 */
72 0x0000, /* R32 */
73 0x0000, /* R33 */
74 0x0100, /* R34 - SPKMIXL Attenuation */
75 0x0000, /* R35 */
76 0x0010, /* R36 - SPKOUT Mixers */
77 0x0140, /* R37 - ClassD3 */
78 0x0039, /* R38 - Speaker Volume Left */
79 0x0000, /* R39 */
80 0x0000, /* R40 */
81 0x0000, /* R41 */
82 0x0000, /* R42 */
83 0x0000, /* R43 */
84 0x0000, /* R44 */
85 0x0000, /* R45 - Output Mixer1 */
86 0x0000, /* R46 - Output Mixer2 */
87 0x0100, /* R47 - Output Mixer3 */
88 0x0100, /* R48 - Output Mixer4 */
89 0x0000, /* R49 */
90 0x0000, /* R50 */
91 0x0000, /* R51 */
92 0x0000, /* R52 */
93 0x0000, /* R53 */
94 0x0000, /* R54 - Speaker Mixer */
95 0x0000, /* R55 */
96 0x0000, /* R56 */
97 0x000D, /* R57 - AntiPOP2 */
98 0x0000, /* R58 */
99 0x0000, /* R59 */
100 0x0000, /* R60 */
101 0x0000, /* R61 */
102 0x0000, /* R62 */
103 0x0000, /* R63 */
104 0x0000, /* R64 */
105 0x0000, /* R65 */
106 0x0000, /* R66 */
107 0x0000, /* R67 */
108 0x0000, /* R68 */
109 0x0000, /* R69 */
110 0x0000, /* R70 - Write Sequencer 0 */
111 0x0000, /* R71 - Write Sequencer 1 */
112 0x0000, /* R72 - Write Sequencer 2 */
113 0x0000, /* R73 - Write Sequencer 3 */
114 0x0000, /* R74 - Write Sequencer 4 */
115 0x0000, /* R75 - Write Sequencer 5 */
116 0x1F25, /* R76 - Charge Pump 1 */
117 0x0000, /* R77 */
118 0x0000, /* R78 */
119 0x0000, /* R79 */
120 0x0000, /* R80 */
121 0x0000, /* R81 */
122 0x0000, /* R82 */
123 0x0000, /* R83 */
124 0x0000, /* R84 - DC Servo 0 */
125 0x054A, /* R85 - DC Servo 1 */
126 0x0000, /* R86 */
127 0x0000, /* R87 - DC Servo 3 */
128 0x0000, /* R88 - DC Servo Readback 0 */
129 0x0000, /* R89 - DC Servo Readback 1 */
130 0x0000, /* R90 - DC Servo Readback 2 */
131 0x0000, /* R91 */
132 0x0000, /* R92 */
133 0x0000, /* R93 */
134 0x0000, /* R94 */
135 0x0000, /* R95 */
136 0x0100, /* R96 - Analogue HP 0 */
137 0x0000, /* R97 */
138 0x8640, /* R98 - AGC Control 0 */
139 0xC000, /* R99 - AGC Control 1 */
140 0x0200, /* R100 - AGC Control 2 */
141};
142
143/* This struct is used to save the context */
144struct wm9090_priv {
145 /* We're not really registering as a CODEC since ASoC core
146 * does not yet support multiple CODECs but having the CODEC
147 * structure means we can reuse some of the ASoC core
148 * features.
149 */
150 struct snd_soc_codec codec;
151 struct mutex mutex;
152 u16 reg_cache[WM9090_MAX_REGISTER + 1];
153 struct wm9090_platform_data pdata;
154};
155
156static int wm9090_volatile(unsigned int reg)
157{
158 switch (reg) {
159 case WM9090_SOFTWARE_RESET:
160 case WM9090_DC_SERVO_0:
161 case WM9090_DC_SERVO_READBACK_0:
162 case WM9090_DC_SERVO_READBACK_1:
163 case WM9090_DC_SERVO_READBACK_2:
164 return 1;
165
166 default:
167 return 0;
168 }
169}
170
171static void wait_for_dc_servo(struct snd_soc_codec *codec)
172{
173 unsigned int reg;
174 int count = 0;
175
176 dev_dbg(codec->dev, "Waiting for DC servo...\n");
177 do {
178 count++;
179 msleep(1);
180 reg = snd_soc_read(codec, WM9090_DC_SERVO_READBACK_0);
181 dev_dbg(codec->dev, "DC servo status: %x\n", reg);
182 } while ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
183 != WM9090_DCS_CAL_COMPLETE_MASK && count < 1000);
184
185 if ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
186 != WM9090_DCS_CAL_COMPLETE_MASK)
187 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
188}
189
190static const unsigned int in_tlv[] = {
191 TLV_DB_RANGE_HEAD(6),
192 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
193 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0),
194 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0),
195};
196static const unsigned int mix_tlv[] = {
197 TLV_DB_RANGE_HEAD(4),
198 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0),
199 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0),
200};
201static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
202static const unsigned int spkboost_tlv[] = {
203 TLV_DB_RANGE_HEAD(7),
204 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
205 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
206};
207
208static const struct snd_kcontrol_new wm9090_controls[] = {
209SOC_SINGLE_TLV("IN1A Volume", WM9090_IN1_LINE_INPUT_A_VOLUME, 0, 6, 0,
210 in_tlv),
211SOC_SINGLE("IN1A Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 7, 1, 1),
212SOC_SINGLE("IN1A ZC Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 6, 1, 0),
213
214SOC_SINGLE_TLV("IN2A Volume", WM9090_IN2_LINE_INPUT_A_VOLUME, 0, 6, 0,
215 in_tlv),
216SOC_SINGLE("IN2A Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 7, 1, 1),
217SOC_SINGLE("IN2A ZC Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 6, 1, 0),
218
219SOC_SINGLE("MIXOUTL Switch", WM9090_OUTPUT_MIXER3, 8, 1, 1),
220SOC_SINGLE_TLV("MIXOUTL IN1A Volume", WM9090_OUTPUT_MIXER3, 6, 3, 1,
221 mix_tlv),
222SOC_SINGLE_TLV("MIXOUTL IN2A Volume", WM9090_OUTPUT_MIXER3, 2, 3, 1,
223 mix_tlv),
224
225SOC_SINGLE("MIXOUTR Switch", WM9090_OUTPUT_MIXER4, 8, 1, 1),
226SOC_SINGLE_TLV("MIXOUTR IN1A Volume", WM9090_OUTPUT_MIXER4, 6, 3, 1,
227 mix_tlv),
228SOC_SINGLE_TLV("MIXOUTR IN2A Volume", WM9090_OUTPUT_MIXER4, 2, 3, 1,
229 mix_tlv),
230
231SOC_SINGLE("SPKMIX Switch", WM9090_SPKMIXL_ATTENUATION, 8, 1, 1),
232SOC_SINGLE_TLV("SPKMIX IN1A Volume", WM9090_SPKMIXL_ATTENUATION, 6, 3, 1,
233 mix_tlv),
234SOC_SINGLE_TLV("SPKMIX IN2A Volume", WM9090_SPKMIXL_ATTENUATION, 2, 3, 1,
235 mix_tlv),
236
237SOC_DOUBLE_R_TLV("Headphone Volume", WM9090_LEFT_OUTPUT_VOLUME,
238 WM9090_RIGHT_OUTPUT_VOLUME, 0, 63, 0, out_tlv),
239SOC_DOUBLE_R("Headphone Switch", WM9090_LEFT_OUTPUT_VOLUME,
240 WM9090_RIGHT_OUTPUT_VOLUME, 6, 1, 1),
241SOC_DOUBLE_R("Headphone ZC Switch", WM9090_LEFT_OUTPUT_VOLUME,
242 WM9090_RIGHT_OUTPUT_VOLUME, 7, 1, 0),
243
244SOC_SINGLE_TLV("Speaker Volume", WM9090_SPEAKER_VOLUME_LEFT, 0, 63, 0,
245 out_tlv),
246SOC_SINGLE("Speaker Switch", WM9090_SPEAKER_VOLUME_LEFT, 6, 1, 1),
247SOC_SINGLE("Speaker ZC Switch", WM9090_SPEAKER_VOLUME_LEFT, 7, 1, 0),
248SOC_SINGLE_TLV("Speaker Boost Volume", WM9090_CLASSD3, 3, 7, 0, spkboost_tlv),
249};
250
251static const struct snd_kcontrol_new wm9090_in1_se_controls[] = {
252SOC_SINGLE_TLV("IN1B Volume", WM9090_IN1_LINE_INPUT_B_VOLUME, 0, 6, 0,
253 in_tlv),
254SOC_SINGLE("IN1B Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 7, 1, 1),
255SOC_SINGLE("IN1B ZC Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 6, 1, 0),
256
257SOC_SINGLE_TLV("SPKMIX IN1B Volume", WM9090_SPKMIXL_ATTENUATION, 4, 3, 1,
258 mix_tlv),
259SOC_SINGLE_TLV("MIXOUTL IN1B Volume", WM9090_OUTPUT_MIXER3, 4, 3, 1,
260 mix_tlv),
261SOC_SINGLE_TLV("MIXOUTR IN1B Volume", WM9090_OUTPUT_MIXER4, 4, 3, 1,
262 mix_tlv),
263};
264
265static const struct snd_kcontrol_new wm9090_in2_se_controls[] = {
266SOC_SINGLE_TLV("IN2B Volume", WM9090_IN2_LINE_INPUT_B_VOLUME, 0, 6, 0,
267 in_tlv),
268SOC_SINGLE("IN2B Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 7, 1, 1),
269SOC_SINGLE("IN2B ZC Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 6, 1, 0),
270
271SOC_SINGLE_TLV("SPKMIX IN2B Volume", WM9090_SPKMIXL_ATTENUATION, 0, 3, 1,
272 mix_tlv),
273SOC_SINGLE_TLV("MIXOUTL IN2B Volume", WM9090_OUTPUT_MIXER3, 0, 3, 1,
274 mix_tlv),
275SOC_SINGLE_TLV("MIXOUTR IN2B Volume", WM9090_OUTPUT_MIXER4, 0, 3, 1,
276 mix_tlv),
277};
278
279static int hp_ev(struct snd_soc_dapm_widget *w,
280 struct snd_kcontrol *kcontrol, int event)
281{
282 struct snd_soc_codec *codec = w->codec;
283 unsigned int reg = snd_soc_read(codec, WM9090_ANALOGUE_HP_0);
284
285 switch (event) {
286 case SND_SOC_DAPM_POST_PMU:
287 snd_soc_update_bits(codec, WM9090_CHARGE_PUMP_1,
288 WM9090_CP_ENA, WM9090_CP_ENA);
289
290 msleep(5);
291
292 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
293 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
294 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA);
295
296 reg |= WM9090_HPOUT1L_DLY | WM9090_HPOUT1R_DLY;
297 snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
298
299 /* Start the DC servo. We don't currently use the
300 * ability to save the state since we don't have full
301 * control of the analogue paths and they can change
302 * DC offsets; see the WM8904 driver for an example of
303 * doing so.
304 */
305 snd_soc_write(codec, WM9090_DC_SERVO_0,
306 WM9090_DCS_ENA_CHAN_0 |
307 WM9090_DCS_ENA_CHAN_1 |
308 WM9090_DCS_TRIG_STARTUP_1 |
309 WM9090_DCS_TRIG_STARTUP_0);
310 wait_for_dc_servo(codec);
311
312 reg |= WM9090_HPOUT1R_OUTP | WM9090_HPOUT1R_RMV_SHORT |
313 WM9090_HPOUT1L_OUTP | WM9090_HPOUT1L_RMV_SHORT;
314 snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
315 break;
316
317 case SND_SOC_DAPM_PRE_PMD:
318 reg &= ~(WM9090_HPOUT1L_RMV_SHORT |
319 WM9090_HPOUT1L_DLY |
320 WM9090_HPOUT1L_OUTP |
321 WM9090_HPOUT1R_RMV_SHORT |
322 WM9090_HPOUT1R_DLY |
323 WM9090_HPOUT1R_OUTP);
324
325 snd_soc_write(codec, WM9090_ANALOGUE_HP_0, reg);
326
327 snd_soc_write(codec, WM9090_DC_SERVO_0, 0);
328
329 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
330 WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
331 0);
332
333 snd_soc_update_bits(codec, WM9090_CHARGE_PUMP_1,
334 WM9090_CP_ENA, 0);
335 break;
336 }
337
338 return 0;
339}
340
341static const struct snd_kcontrol_new spkmix[] = {
342SOC_DAPM_SINGLE("IN1A Switch", WM9090_SPEAKER_MIXER, 6, 1, 0),
343SOC_DAPM_SINGLE("IN1B Switch", WM9090_SPEAKER_MIXER, 4, 1, 0),
344SOC_DAPM_SINGLE("IN2A Switch", WM9090_SPEAKER_MIXER, 2, 1, 0),
345SOC_DAPM_SINGLE("IN2B Switch", WM9090_SPEAKER_MIXER, 0, 1, 0),
346};
347
348static const struct snd_kcontrol_new spkout[] = {
349SOC_DAPM_SINGLE("Mixer Switch", WM9090_SPKOUT_MIXERS, 4, 1, 0),
350};
351
352static const struct snd_kcontrol_new mixoutl[] = {
353SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER1, 6, 1, 0),
354SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER1, 4, 1, 0),
355SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER1, 2, 1, 0),
356SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER1, 0, 1, 0),
357};
358
359static const struct snd_kcontrol_new mixoutr[] = {
360SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER2, 6, 1, 0),
361SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER2, 4, 1, 0),
362SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER2, 2, 1, 0),
363SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER2, 0, 1, 0),
364};
365
366static const struct snd_soc_dapm_widget wm9090_dapm_widgets[] = {
367SND_SOC_DAPM_INPUT("IN1+"),
368SND_SOC_DAPM_INPUT("IN1-"),
369SND_SOC_DAPM_INPUT("IN2+"),
370SND_SOC_DAPM_INPUT("IN2-"),
371
372SND_SOC_DAPM_SUPPLY("OSC", WM9090_POWER_MANAGEMENT_1, 3, 0, NULL, 0),
373
374SND_SOC_DAPM_PGA("IN1A PGA", WM9090_POWER_MANAGEMENT_2, 7, 0, NULL, 0),
375SND_SOC_DAPM_PGA("IN1B PGA", WM9090_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
376SND_SOC_DAPM_PGA("IN2A PGA", WM9090_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
377SND_SOC_DAPM_PGA("IN2B PGA", WM9090_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
378
379SND_SOC_DAPM_MIXER("SPKMIX", WM9090_POWER_MANAGEMENT_3, 3, 0,
380 spkmix, ARRAY_SIZE(spkmix)),
381SND_SOC_DAPM_MIXER("MIXOUTL", WM9090_POWER_MANAGEMENT_3, 5, 0,
382 mixoutl, ARRAY_SIZE(mixoutl)),
383SND_SOC_DAPM_MIXER("MIXOUTR", WM9090_POWER_MANAGEMENT_3, 4, 0,
384 mixoutr, ARRAY_SIZE(mixoutr)),
385
386SND_SOC_DAPM_PGA_E("HP PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
387 hp_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
388
389SND_SOC_DAPM_PGA("SPKPGA", WM9090_POWER_MANAGEMENT_3, 8, 0, NULL, 0),
390SND_SOC_DAPM_MIXER("SPKOUT", WM9090_POWER_MANAGEMENT_1, 12, 0,
391 spkout, ARRAY_SIZE(spkout)),
392
393SND_SOC_DAPM_OUTPUT("HPR"),
394SND_SOC_DAPM_OUTPUT("HPL"),
395SND_SOC_DAPM_OUTPUT("Speaker"),
396};
397
398static const struct snd_soc_dapm_route audio_map[] = {
399 { "IN1A PGA", NULL, "IN1+" },
400 { "IN2A PGA", NULL, "IN2+" },
401
402 { "SPKMIX", "IN1A Switch", "IN1A PGA" },
403 { "SPKMIX", "IN2A Switch", "IN2A PGA" },
404
405 { "MIXOUTL", "IN1A Switch", "IN1A PGA" },
406 { "MIXOUTL", "IN2A Switch", "IN2A PGA" },
407
408 { "MIXOUTR", "IN1A Switch", "IN1A PGA" },
409 { "MIXOUTR", "IN2A Switch", "IN2A PGA" },
410
411 { "HP PGA", NULL, "OSC" },
412 { "HP PGA", NULL, "MIXOUTL" },
413 { "HP PGA", NULL, "MIXOUTR" },
414
415 { "HPL", NULL, "HP PGA" },
416 { "HPR", NULL, "HP PGA" },
417
418 { "SPKPGA", NULL, "OSC" },
419 { "SPKPGA", NULL, "SPKMIX" },
420
421 { "SPKOUT", "Mixer Switch", "SPKPGA" },
422
423 { "Speaker", NULL, "SPKOUT" },
424};
425
426static const struct snd_soc_dapm_route audio_map_in1_se[] = {
427 { "IN1B PGA", NULL, "IN1-" },
428
429 { "SPKMIX", "IN1B Switch", "IN1B PGA" },
430 { "MIXOUTL", "IN1B Switch", "IN1B PGA" },
431 { "MIXOUTR", "IN1B Switch", "IN1B PGA" },
432};
433
434static const struct snd_soc_dapm_route audio_map_in1_diff[] = {
435 { "IN1A PGA", NULL, "IN1-" },
436};
437
438static const struct snd_soc_dapm_route audio_map_in2_se[] = {
439 { "IN2B PGA", NULL, "IN2-" },
440
441 { "SPKMIX", "IN2B Switch", "IN2B PGA" },
442 { "MIXOUTL", "IN2B Switch", "IN2B PGA" },
443 { "MIXOUTR", "IN2B Switch", "IN2B PGA" },
444};
445
446static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
447 { "IN2A PGA", NULL, "IN2-" },
448};
449
450static int wm9090_add_controls(struct snd_soc_codec *codec)
451{
452 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
453 int i;
454
455 snd_soc_dapm_new_controls(codec, wm9090_dapm_widgets,
456 ARRAY_SIZE(wm9090_dapm_widgets));
457
458 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
459
460 snd_soc_add_controls(codec, wm9090_controls,
461 ARRAY_SIZE(wm9090_controls));
462
463 if (wm9090->pdata.lin1_diff) {
464 snd_soc_dapm_add_routes(codec, audio_map_in1_diff,
465 ARRAY_SIZE(audio_map_in1_diff));
466 } else {
467 snd_soc_dapm_add_routes(codec, audio_map_in1_se,
468 ARRAY_SIZE(audio_map_in1_se));
469 snd_soc_add_controls(codec, wm9090_in1_se_controls,
470 ARRAY_SIZE(wm9090_in1_se_controls));
471 }
472
473 if (wm9090->pdata.lin2_diff) {
474 snd_soc_dapm_add_routes(codec, audio_map_in2_diff,
475 ARRAY_SIZE(audio_map_in2_diff));
476 } else {
477 snd_soc_dapm_add_routes(codec, audio_map_in2_se,
478 ARRAY_SIZE(audio_map_in2_se));
479 snd_soc_add_controls(codec, wm9090_in2_se_controls,
480 ARRAY_SIZE(wm9090_in2_se_controls));
481 }
482
483 if (wm9090->pdata.agc_ena) {
484 for (i = 0; i < ARRAY_SIZE(wm9090->pdata.agc); i++)
485 snd_soc_write(codec, WM9090_AGC_CONTROL_0 + i,
486 wm9090->pdata.agc[i]);
487 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_3,
488 WM9090_AGC_ENA, WM9090_AGC_ENA);
489 } else {
490 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_3,
491 WM9090_AGC_ENA, 0);
492 }
493
494 return 0;
495
496}
497
498/*
499 * The machine driver should call this from their set_bias_level; if there
500 * isn't one then this can just be set as the set_bias_level function.
501 */
502static int wm9090_set_bias_level(struct snd_soc_codec *codec,
503 enum snd_soc_bias_level level)
504{
505 u16 *reg_cache = codec->reg_cache;
506 int i, ret;
507
508 switch (level) {
509 case SND_SOC_BIAS_ON:
510 break;
511
512 case SND_SOC_BIAS_PREPARE:
513 snd_soc_update_bits(codec, WM9090_ANTIPOP2, WM9090_VMID_ENA,
514 WM9090_VMID_ENA);
515 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
516 WM9090_BIAS_ENA |
517 WM9090_VMID_RES_MASK,
518 WM9090_BIAS_ENA |
519 1 << WM9090_VMID_RES_SHIFT);
520 msleep(1); /* Probably an overestimate */
521 break;
522
523 case SND_SOC_BIAS_STANDBY:
524 if (codec->bias_level == SND_SOC_BIAS_OFF) {
525 /* Restore the register cache */
526 for (i = 1; i < codec->reg_cache_size; i++) {
527 if (reg_cache[i] == wm9090_reg_defaults[i])
528 continue;
529 if (wm9090_volatile(i))
530 continue;
531
532 ret = snd_soc_write(codec, i, reg_cache[i]);
533 if (ret != 0)
534 dev_warn(codec->dev,
535 "Failed to restore register %d: %d\n",
536 i, ret);
537 }
538 }
539
540 /* We keep VMID off during standby since the combination of
541 * ground referenced outputs and class D speaker mean that
542 * latency is not an issue.
543 */
544 snd_soc_update_bits(codec, WM9090_POWER_MANAGEMENT_1,
545 WM9090_BIAS_ENA | WM9090_VMID_RES_MASK, 0);
546 snd_soc_update_bits(codec, WM9090_ANTIPOP2,
547 WM9090_VMID_ENA, 0);
548 break;
549
550 case SND_SOC_BIAS_OFF:
551 break;
552 }
553
554 codec->bias_level = level;
555
556 return 0;
557}
558
559static int wm9090_probe(struct platform_device *pdev)
560{
561 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
562 struct snd_soc_codec *codec;
563 int ret = 0;
564
565 if (wm9090_codec == NULL) {
566 dev_err(&pdev->dev, "Codec device not registered\n");
567 return -ENODEV;
568 }
569
570 socdev->card->codec = wm9090_codec;
571 codec = wm9090_codec;
572
573 /* register pcms */
574 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
575 if (ret < 0) {
576 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
577 goto pcm_err;
578 }
579
580 wm9090_add_controls(codec);
581
582 return 0;
583
584pcm_err:
585 return ret;
586}
587
588#ifdef CONFIG_PM
589static int wm9090_suspend(struct platform_device *pdev, pm_message_t state)
590{
591 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
592 struct snd_soc_codec *codec = socdev->card->codec;
593
594 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
595
596 return 0;
597}
598
599static int wm9090_resume(struct platform_device *pdev)
600{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = socdev->card->codec;
603
604 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
605
606 return 0;
607}
608#else
609#define wm9090_suspend NULL
610#define wm9090_resume NULL
611#endif
612
613static int wm9090_remove(struct platform_device *pdev)
614{
615 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
616
617 snd_soc_free_pcms(socdev);
618 snd_soc_dapm_free(socdev);
619
620 return 0;
621}
622
623struct snd_soc_codec_device soc_codec_dev_wm9090 = {
624 .probe = wm9090_probe,
625 .remove = wm9090_remove,
626 .suspend = wm9090_suspend,
627 .resume = wm9090_resume,
628};
629EXPORT_SYMBOL_GPL(soc_codec_dev_wm9090);
630
631static int wm9090_i2c_probe(struct i2c_client *i2c,
632 const struct i2c_device_id *id)
633{
634 struct wm9090_priv *wm9090;
635 struct snd_soc_codec *codec;
636 int ret;
637
638 wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL);
639 if (wm9090 == NULL) {
640 dev_err(&i2c->dev, "Can not allocate memory\n");
641 return -ENOMEM;
642 }
643 codec = &wm9090->codec;
644
645 if (i2c->dev.platform_data)
646 memcpy(&wm9090->pdata, i2c->dev.platform_data,
647 sizeof(wm9090->pdata));
648
649 wm9090_codec = codec;
650
651 i2c_set_clientdata(i2c, wm9090);
652
653 mutex_init(&codec->mutex);
654 INIT_LIST_HEAD(&codec->dapm_widgets);
655 INIT_LIST_HEAD(&codec->dapm_paths);
656
657 codec->control_data = i2c;
658 snd_soc_codec_set_drvdata(codec, wm9090);
659 codec->dev = &i2c->dev;
660 codec->name = "WM9090";
661 codec->owner = THIS_MODULE;
662 codec->bias_level = SND_SOC_BIAS_OFF;
663 codec->set_bias_level = wm9090_set_bias_level,
664 codec->reg_cache_size = WM9090_MAX_REGISTER + 1;
665 codec->reg_cache = &wm9090->reg_cache;
666 codec->volatile_register = wm9090_volatile;
667
668 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
669 if (ret != 0) {
670 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
671 goto err;
672 }
673
674 memcpy(&wm9090->reg_cache, wm9090_reg_defaults,
675 sizeof(wm9090->reg_cache));
676
677 ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
678 if (ret < 0)
679 goto err;
680 if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
681 dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", ret);
682 ret = -EINVAL;
683 goto err;
684 }
685
686 ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
687 if (ret < 0)
688 goto err;
689
690 /* Configure some defaults; they will be written out when we
691 * bring the bias up.
692 */
693 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
694 | WM9090_IN1A_ZC;
695 wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
696 | WM9090_IN1B_ZC;
697 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
698 | WM9090_IN2A_ZC;
699 wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
700 | WM9090_IN2B_ZC;
701 wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
702 WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
703 wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
704 WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
705 wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
706 WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
707
708 wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
709
710 wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
711
712 ret = snd_soc_register_codec(codec);
713 if (ret != 0) {
714 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
715 goto err_bias;
716 }
717
718 return 0;
719
720err_bias:
721 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
722err:
723 kfree(wm9090);
724 i2c_set_clientdata(i2c, NULL);
725 wm9090_codec = NULL;
726
727 return ret;
728}
729
730static int wm9090_i2c_remove(struct i2c_client *i2c)
731{
732 struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
733 struct snd_soc_codec *codec = &wm9090->codec;
734
735 snd_soc_unregister_codec(codec);
736 wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF);
737 kfree(wm9090);
738 wm9090_codec = NULL;
739
740 return 0;
741}
742
743static const struct i2c_device_id wm9090_id[] = {
744 { "wm9090", 0 },
745 { }
746};
747MODULE_DEVICE_TABLE(i2c, wm9090_id);
748
749static struct i2c_driver wm9090_i2c_driver = {
750 .driver = {
751 .name = "wm9090",
752 .owner = THIS_MODULE,
753 },
754 .probe = wm9090_i2c_probe,
755 .remove = __devexit_p(wm9090_i2c_remove),
756 .id_table = wm9090_id,
757};
758
759static int __init wm9090_init(void)
760{
761 return i2c_add_driver(&wm9090_i2c_driver);
762}
763module_init(wm9090_init);
764
765static void __exit wm9090_exit(void)
766{
767 i2c_del_driver(&wm9090_i2c_driver);
768}
769module_exit(wm9090_exit);
770
771MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
772MODULE_DESCRIPTION("WM9090 ASoC driver");
773MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm9090.h b/sound/soc/codecs/wm9090.h
new file mode 100644
index 000000000000..b08eab932a5b
--- /dev/null
+++ b/sound/soc/codecs/wm9090.h
@@ -0,0 +1,715 @@
1/*
2 * ALSA SoC WM9090 driver
3 *
4 * Copyright 2009 Wolfson Microelectronics
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#ifndef __WM9090_H
24#define __WM9090_H
25
26extern struct snd_soc_codec_device soc_codec_dev_wm9090;
27
28/*
29 * Register values.
30 */
31#define WM9090_SOFTWARE_RESET 0x00
32#define WM9090_POWER_MANAGEMENT_1 0x01
33#define WM9090_POWER_MANAGEMENT_2 0x02
34#define WM9090_POWER_MANAGEMENT_3 0x03
35#define WM9090_CLOCKING_1 0x06
36#define WM9090_IN1_LINE_CONTROL 0x16
37#define WM9090_IN2_LINE_CONTROL 0x17
38#define WM9090_IN1_LINE_INPUT_A_VOLUME 0x18
39#define WM9090_IN1_LINE_INPUT_B_VOLUME 0x19
40#define WM9090_IN2_LINE_INPUT_A_VOLUME 0x1A
41#define WM9090_IN2_LINE_INPUT_B_VOLUME 0x1B
42#define WM9090_LEFT_OUTPUT_VOLUME 0x1C
43#define WM9090_RIGHT_OUTPUT_VOLUME 0x1D
44#define WM9090_SPKMIXL_ATTENUATION 0x22
45#define WM9090_SPKOUT_MIXERS 0x24
46#define WM9090_CLASSD3 0x25
47#define WM9090_SPEAKER_VOLUME_LEFT 0x26
48#define WM9090_OUTPUT_MIXER1 0x2D
49#define WM9090_OUTPUT_MIXER2 0x2E
50#define WM9090_OUTPUT_MIXER3 0x2F
51#define WM9090_OUTPUT_MIXER4 0x30
52#define WM9090_SPEAKER_MIXER 0x36
53#define WM9090_ANTIPOP2 0x39
54#define WM9090_WRITE_SEQUENCER_0 0x46
55#define WM9090_WRITE_SEQUENCER_1 0x47
56#define WM9090_WRITE_SEQUENCER_2 0x48
57#define WM9090_WRITE_SEQUENCER_3 0x49
58#define WM9090_WRITE_SEQUENCER_4 0x4A
59#define WM9090_WRITE_SEQUENCER_5 0x4B
60#define WM9090_CHARGE_PUMP_1 0x4C
61#define WM9090_DC_SERVO_0 0x54
62#define WM9090_DC_SERVO_1 0x55
63#define WM9090_DC_SERVO_3 0x57
64#define WM9090_DC_SERVO_READBACK_0 0x58
65#define WM9090_DC_SERVO_READBACK_1 0x59
66#define WM9090_DC_SERVO_READBACK_2 0x5A
67#define WM9090_ANALOGUE_HP_0 0x60
68#define WM9090_AGC_CONTROL_0 0x62
69#define WM9090_AGC_CONTROL_1 0x63
70#define WM9090_AGC_CONTROL_2 0x64
71
72#define WM9090_REGISTER_COUNT 40
73#define WM9090_MAX_REGISTER 0x64
74
75/*
76 * Field Definitions.
77 */
78
79/*
80 * R0 (0x00) - Software Reset
81 */
82#define WM9090_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
83#define WM9090_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
84#define WM9090_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
85
86/*
87 * R1 (0x01) - Power Management (1)
88 */
89#define WM9090_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
90#define WM9090_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
91#define WM9090_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
92#define WM9090_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
93#define WM9090_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
94#define WM9090_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
95#define WM9090_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
96#define WM9090_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
97#define WM9090_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
98#define WM9090_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
99#define WM9090_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
100#define WM9090_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
101#define WM9090_OSC_ENA 0x0008 /* OSC_ENA */
102#define WM9090_OSC_ENA_MASK 0x0008 /* OSC_ENA */
103#define WM9090_OSC_ENA_SHIFT 3 /* OSC_ENA */
104#define WM9090_OSC_ENA_WIDTH 1 /* OSC_ENA */
105#define WM9090_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
106#define WM9090_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
107#define WM9090_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
108#define WM9090_BIAS_ENA 0x0001 /* BIAS_ENA */
109#define WM9090_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
110#define WM9090_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
111#define WM9090_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
112
113/*
114 * R2 (0x02) - Power Management (2)
115 */
116#define WM9090_TSHUT 0x8000 /* TSHUT */
117#define WM9090_TSHUT_MASK 0x8000 /* TSHUT */
118#define WM9090_TSHUT_SHIFT 15 /* TSHUT */
119#define WM9090_TSHUT_WIDTH 1 /* TSHUT */
120#define WM9090_TSHUT_ENA 0x4000 /* TSHUT_ENA */
121#define WM9090_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
122#define WM9090_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
123#define WM9090_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
124#define WM9090_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
125#define WM9090_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
126#define WM9090_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
127#define WM9090_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
128#define WM9090_IN1A_ENA 0x0080 /* IN1A_ENA */
129#define WM9090_IN1A_ENA_MASK 0x0080 /* IN1A_ENA */
130#define WM9090_IN1A_ENA_SHIFT 7 /* IN1A_ENA */
131#define WM9090_IN1A_ENA_WIDTH 1 /* IN1A_ENA */
132#define WM9090_IN1B_ENA 0x0040 /* IN1B_ENA */
133#define WM9090_IN1B_ENA_MASK 0x0040 /* IN1B_ENA */
134#define WM9090_IN1B_ENA_SHIFT 6 /* IN1B_ENA */
135#define WM9090_IN1B_ENA_WIDTH 1 /* IN1B_ENA */
136#define WM9090_IN2A_ENA 0x0020 /* IN2A_ENA */
137#define WM9090_IN2A_ENA_MASK 0x0020 /* IN2A_ENA */
138#define WM9090_IN2A_ENA_SHIFT 5 /* IN2A_ENA */
139#define WM9090_IN2A_ENA_WIDTH 1 /* IN2A_ENA */
140#define WM9090_IN2B_ENA 0x0010 /* IN2B_ENA */
141#define WM9090_IN2B_ENA_MASK 0x0010 /* IN2B_ENA */
142#define WM9090_IN2B_ENA_SHIFT 4 /* IN2B_ENA */
143#define WM9090_IN2B_ENA_WIDTH 1 /* IN2B_ENA */
144
145/*
146 * R3 (0x03) - Power Management (3)
147 */
148#define WM9090_AGC_ENA 0x4000 /* AGC_ENA */
149#define WM9090_AGC_ENA_MASK 0x4000 /* AGC_ENA */
150#define WM9090_AGC_ENA_SHIFT 14 /* AGC_ENA */
151#define WM9090_AGC_ENA_WIDTH 1 /* AGC_ENA */
152#define WM9090_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
153#define WM9090_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
154#define WM9090_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
155#define WM9090_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
156#define WM9090_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
157#define WM9090_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
158#define WM9090_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
159#define WM9090_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
160#define WM9090_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
161#define WM9090_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
162#define WM9090_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
163#define WM9090_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
164#define WM9090_SPKMIX_ENA 0x0008 /* SPKMIX_ENA */
165#define WM9090_SPKMIX_ENA_MASK 0x0008 /* SPKMIX_ENA */
166#define WM9090_SPKMIX_ENA_SHIFT 3 /* SPKMIX_ENA */
167#define WM9090_SPKMIX_ENA_WIDTH 1 /* SPKMIX_ENA */
168
169/*
170 * R6 (0x06) - Clocking 1
171 */
172#define WM9090_TOCLK_RATE 0x8000 /* TOCLK_RATE */
173#define WM9090_TOCLK_RATE_MASK 0x8000 /* TOCLK_RATE */
174#define WM9090_TOCLK_RATE_SHIFT 15 /* TOCLK_RATE */
175#define WM9090_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
176#define WM9090_TOCLK_ENA 0x4000 /* TOCLK_ENA */
177#define WM9090_TOCLK_ENA_MASK 0x4000 /* TOCLK_ENA */
178#define WM9090_TOCLK_ENA_SHIFT 14 /* TOCLK_ENA */
179#define WM9090_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
180
181/*
182 * R22 (0x16) - IN1 Line Control
183 */
184#define WM9090_IN1_DIFF 0x0002 /* IN1_DIFF */
185#define WM9090_IN1_DIFF_MASK 0x0002 /* IN1_DIFF */
186#define WM9090_IN1_DIFF_SHIFT 1 /* IN1_DIFF */
187#define WM9090_IN1_DIFF_WIDTH 1 /* IN1_DIFF */
188#define WM9090_IN1_CLAMP 0x0001 /* IN1_CLAMP */
189#define WM9090_IN1_CLAMP_MASK 0x0001 /* IN1_CLAMP */
190#define WM9090_IN1_CLAMP_SHIFT 0 /* IN1_CLAMP */
191#define WM9090_IN1_CLAMP_WIDTH 1 /* IN1_CLAMP */
192
193/*
194 * R23 (0x17) - IN2 Line Control
195 */
196#define WM9090_IN2_DIFF 0x0002 /* IN2_DIFF */
197#define WM9090_IN2_DIFF_MASK 0x0002 /* IN2_DIFF */
198#define WM9090_IN2_DIFF_SHIFT 1 /* IN2_DIFF */
199#define WM9090_IN2_DIFF_WIDTH 1 /* IN2_DIFF */
200#define WM9090_IN2_CLAMP 0x0001 /* IN2_CLAMP */
201#define WM9090_IN2_CLAMP_MASK 0x0001 /* IN2_CLAMP */
202#define WM9090_IN2_CLAMP_SHIFT 0 /* IN2_CLAMP */
203#define WM9090_IN2_CLAMP_WIDTH 1 /* IN2_CLAMP */
204
205/*
206 * R24 (0x18) - IN1 Line Input A Volume
207 */
208#define WM9090_IN1_VU 0x0100 /* IN1_VU */
209#define WM9090_IN1_VU_MASK 0x0100 /* IN1_VU */
210#define WM9090_IN1_VU_SHIFT 8 /* IN1_VU */
211#define WM9090_IN1_VU_WIDTH 1 /* IN1_VU */
212#define WM9090_IN1A_MUTE 0x0080 /* IN1A_MUTE */
213#define WM9090_IN1A_MUTE_MASK 0x0080 /* IN1A_MUTE */
214#define WM9090_IN1A_MUTE_SHIFT 7 /* IN1A_MUTE */
215#define WM9090_IN1A_MUTE_WIDTH 1 /* IN1A_MUTE */
216#define WM9090_IN1A_ZC 0x0040 /* IN1A_ZC */
217#define WM9090_IN1A_ZC_MASK 0x0040 /* IN1A_ZC */
218#define WM9090_IN1A_ZC_SHIFT 6 /* IN1A_ZC */
219#define WM9090_IN1A_ZC_WIDTH 1 /* IN1A_ZC */
220#define WM9090_IN1A_VOL_MASK 0x0007 /* IN1A_VOL - [2:0] */
221#define WM9090_IN1A_VOL_SHIFT 0 /* IN1A_VOL - [2:0] */
222#define WM9090_IN1A_VOL_WIDTH 3 /* IN1A_VOL - [2:0] */
223
224/*
225 * R25 (0x19) - IN1 Line Input B Volume
226 */
227#define WM9090_IN1_VU 0x0100 /* IN1_VU */
228#define WM9090_IN1_VU_MASK 0x0100 /* IN1_VU */
229#define WM9090_IN1_VU_SHIFT 8 /* IN1_VU */
230#define WM9090_IN1_VU_WIDTH 1 /* IN1_VU */
231#define WM9090_IN1B_MUTE 0x0080 /* IN1B_MUTE */
232#define WM9090_IN1B_MUTE_MASK 0x0080 /* IN1B_MUTE */
233#define WM9090_IN1B_MUTE_SHIFT 7 /* IN1B_MUTE */
234#define WM9090_IN1B_MUTE_WIDTH 1 /* IN1B_MUTE */
235#define WM9090_IN1B_ZC 0x0040 /* IN1B_ZC */
236#define WM9090_IN1B_ZC_MASK 0x0040 /* IN1B_ZC */
237#define WM9090_IN1B_ZC_SHIFT 6 /* IN1B_ZC */
238#define WM9090_IN1B_ZC_WIDTH 1 /* IN1B_ZC */
239#define WM9090_IN1B_VOL_MASK 0x0007 /* IN1B_VOL - [2:0] */
240#define WM9090_IN1B_VOL_SHIFT 0 /* IN1B_VOL - [2:0] */
241#define WM9090_IN1B_VOL_WIDTH 3 /* IN1B_VOL - [2:0] */
242
243/*
244 * R26 (0x1A) - IN2 Line Input A Volume
245 */
246#define WM9090_IN2_VU 0x0100 /* IN2_VU */
247#define WM9090_IN2_VU_MASK 0x0100 /* IN2_VU */
248#define WM9090_IN2_VU_SHIFT 8 /* IN2_VU */
249#define WM9090_IN2_VU_WIDTH 1 /* IN2_VU */
250#define WM9090_IN2A_MUTE 0x0080 /* IN2A_MUTE */
251#define WM9090_IN2A_MUTE_MASK 0x0080 /* IN2A_MUTE */
252#define WM9090_IN2A_MUTE_SHIFT 7 /* IN2A_MUTE */
253#define WM9090_IN2A_MUTE_WIDTH 1 /* IN2A_MUTE */
254#define WM9090_IN2A_ZC 0x0040 /* IN2A_ZC */
255#define WM9090_IN2A_ZC_MASK 0x0040 /* IN2A_ZC */
256#define WM9090_IN2A_ZC_SHIFT 6 /* IN2A_ZC */
257#define WM9090_IN2A_ZC_WIDTH 1 /* IN2A_ZC */
258#define WM9090_IN2A_VOL_MASK 0x0007 /* IN2A_VOL - [2:0] */
259#define WM9090_IN2A_VOL_SHIFT 0 /* IN2A_VOL - [2:0] */
260#define WM9090_IN2A_VOL_WIDTH 3 /* IN2A_VOL - [2:0] */
261
262/*
263 * R27 (0x1B) - IN2 Line Input B Volume
264 */
265#define WM9090_IN2_VU 0x0100 /* IN2_VU */
266#define WM9090_IN2_VU_MASK 0x0100 /* IN2_VU */
267#define WM9090_IN2_VU_SHIFT 8 /* IN2_VU */
268#define WM9090_IN2_VU_WIDTH 1 /* IN2_VU */
269#define WM9090_IN2B_MUTE 0x0080 /* IN2B_MUTE */
270#define WM9090_IN2B_MUTE_MASK 0x0080 /* IN2B_MUTE */
271#define WM9090_IN2B_MUTE_SHIFT 7 /* IN2B_MUTE */
272#define WM9090_IN2B_MUTE_WIDTH 1 /* IN2B_MUTE */
273#define WM9090_IN2B_ZC 0x0040 /* IN2B_ZC */
274#define WM9090_IN2B_ZC_MASK 0x0040 /* IN2B_ZC */
275#define WM9090_IN2B_ZC_SHIFT 6 /* IN2B_ZC */
276#define WM9090_IN2B_ZC_WIDTH 1 /* IN2B_ZC */
277#define WM9090_IN2B_VOL_MASK 0x0007 /* IN2B_VOL - [2:0] */
278#define WM9090_IN2B_VOL_SHIFT 0 /* IN2B_VOL - [2:0] */
279#define WM9090_IN2B_VOL_WIDTH 3 /* IN2B_VOL - [2:0] */
280
281/*
282 * R28 (0x1C) - Left Output Volume
283 */
284#define WM9090_HPOUT1_VU 0x0100 /* HPOUT1_VU */
285#define WM9090_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
286#define WM9090_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
287#define WM9090_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
288#define WM9090_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
289#define WM9090_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
290#define WM9090_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
291#define WM9090_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
292#define WM9090_HPOUT1L_MUTE 0x0040 /* HPOUT1L_MUTE */
293#define WM9090_HPOUT1L_MUTE_MASK 0x0040 /* HPOUT1L_MUTE */
294#define WM9090_HPOUT1L_MUTE_SHIFT 6 /* HPOUT1L_MUTE */
295#define WM9090_HPOUT1L_MUTE_WIDTH 1 /* HPOUT1L_MUTE */
296#define WM9090_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
297#define WM9090_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
298#define WM9090_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
299
300/*
301 * R29 (0x1D) - Right Output Volume
302 */
303#define WM9090_HPOUT1_VU 0x0100 /* HPOUT1_VU */
304#define WM9090_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
305#define WM9090_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
306#define WM9090_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
307#define WM9090_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
308#define WM9090_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
309#define WM9090_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
310#define WM9090_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
311#define WM9090_HPOUT1R_MUTE 0x0040 /* HPOUT1R_MUTE */
312#define WM9090_HPOUT1R_MUTE_MASK 0x0040 /* HPOUT1R_MUTE */
313#define WM9090_HPOUT1R_MUTE_SHIFT 6 /* HPOUT1R_MUTE */
314#define WM9090_HPOUT1R_MUTE_WIDTH 1 /* HPOUT1R_MUTE */
315#define WM9090_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
316#define WM9090_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
317#define WM9090_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
318
319/*
320 * R34 (0x22) - SPKMIXL Attenuation
321 */
322#define WM9090_SPKMIX_MUTE 0x0100 /* SPKMIX_MUTE */
323#define WM9090_SPKMIX_MUTE_MASK 0x0100 /* SPKMIX_MUTE */
324#define WM9090_SPKMIX_MUTE_SHIFT 8 /* SPKMIX_MUTE */
325#define WM9090_SPKMIX_MUTE_WIDTH 1 /* SPKMIX_MUTE */
326#define WM9090_IN1A_SPKMIX_VOL_MASK 0x00C0 /* IN1A_SPKMIX_VOL - [7:6] */
327#define WM9090_IN1A_SPKMIX_VOL_SHIFT 6 /* IN1A_SPKMIX_VOL - [7:6] */
328#define WM9090_IN1A_SPKMIX_VOL_WIDTH 2 /* IN1A_SPKMIX_VOL - [7:6] */
329#define WM9090_IN1B_SPKMIX_VOL_MASK 0x0030 /* IN1B_SPKMIX_VOL - [5:4] */
330#define WM9090_IN1B_SPKMIX_VOL_SHIFT 4 /* IN1B_SPKMIX_VOL - [5:4] */
331#define WM9090_IN1B_SPKMIX_VOL_WIDTH 2 /* IN1B_SPKMIX_VOL - [5:4] */
332#define WM9090_IN2A_SPKMIX_VOL_MASK 0x000C /* IN2A_SPKMIX_VOL - [3:2] */
333#define WM9090_IN2A_SPKMIX_VOL_SHIFT 2 /* IN2A_SPKMIX_VOL - [3:2] */
334#define WM9090_IN2A_SPKMIX_VOL_WIDTH 2 /* IN2A_SPKMIX_VOL - [3:2] */
335#define WM9090_IN2B_SPKMIX_VOL_MASK 0x0003 /* IN2B_SPKMIX_VOL - [1:0] */
336#define WM9090_IN2B_SPKMIX_VOL_SHIFT 0 /* IN2B_SPKMIX_VOL - [1:0] */
337#define WM9090_IN2B_SPKMIX_VOL_WIDTH 2 /* IN2B_SPKMIX_VOL - [1:0] */
338
339/*
340 * R36 (0x24) - SPKOUT Mixers
341 */
342#define WM9090_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
343#define WM9090_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
344#define WM9090_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
345#define WM9090_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
346
347/*
348 * R37 (0x25) - ClassD3
349 */
350#define WM9090_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
351#define WM9090_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
352#define WM9090_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
353
354/*
355 * R38 (0x26) - Speaker Volume Left
356 */
357#define WM9090_SPKOUT_VU 0x0100 /* SPKOUT_VU */
358#define WM9090_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
359#define WM9090_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
360#define WM9090_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
361#define WM9090_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
362#define WM9090_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
363#define WM9090_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
364#define WM9090_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
365#define WM9090_SPKOUTL_MUTE 0x0040 /* SPKOUTL_MUTE */
366#define WM9090_SPKOUTL_MUTE_MASK 0x0040 /* SPKOUTL_MUTE */
367#define WM9090_SPKOUTL_MUTE_SHIFT 6 /* SPKOUTL_MUTE */
368#define WM9090_SPKOUTL_MUTE_WIDTH 1 /* SPKOUTL_MUTE */
369#define WM9090_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
370#define WM9090_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
371#define WM9090_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
372
373/*
374 * R45 (0x2D) - Output Mixer1
375 */
376#define WM9090_IN1A_TO_MIXOUTL 0x0040 /* IN1A_TO_MIXOUTL */
377#define WM9090_IN1A_TO_MIXOUTL_MASK 0x0040 /* IN1A_TO_MIXOUTL */
378#define WM9090_IN1A_TO_MIXOUTL_SHIFT 6 /* IN1A_TO_MIXOUTL */
379#define WM9090_IN1A_TO_MIXOUTL_WIDTH 1 /* IN1A_TO_MIXOUTL */
380#define WM9090_IN2A_TO_MIXOUTL 0x0004 /* IN2A_TO_MIXOUTL */
381#define WM9090_IN2A_TO_MIXOUTL_MASK 0x0004 /* IN2A_TO_MIXOUTL */
382#define WM9090_IN2A_TO_MIXOUTL_SHIFT 2 /* IN2A_TO_MIXOUTL */
383#define WM9090_IN2A_TO_MIXOUTL_WIDTH 1 /* IN2A_TO_MIXOUTL */
384
385/*
386 * R46 (0x2E) - Output Mixer2
387 */
388#define WM9090_IN1A_TO_MIXOUTR 0x0040 /* IN1A_TO_MIXOUTR */
389#define WM9090_IN1A_TO_MIXOUTR_MASK 0x0040 /* IN1A_TO_MIXOUTR */
390#define WM9090_IN1A_TO_MIXOUTR_SHIFT 6 /* IN1A_TO_MIXOUTR */
391#define WM9090_IN1A_TO_MIXOUTR_WIDTH 1 /* IN1A_TO_MIXOUTR */
392#define WM9090_IN1B_TO_MIXOUTR 0x0010 /* IN1B_TO_MIXOUTR */
393#define WM9090_IN1B_TO_MIXOUTR_MASK 0x0010 /* IN1B_TO_MIXOUTR */
394#define WM9090_IN1B_TO_MIXOUTR_SHIFT 4 /* IN1B_TO_MIXOUTR */
395#define WM9090_IN1B_TO_MIXOUTR_WIDTH 1 /* IN1B_TO_MIXOUTR */
396#define WM9090_IN2A_TO_MIXOUTR 0x0004 /* IN2A_TO_MIXOUTR */
397#define WM9090_IN2A_TO_MIXOUTR_MASK 0x0004 /* IN2A_TO_MIXOUTR */
398#define WM9090_IN2A_TO_MIXOUTR_SHIFT 2 /* IN2A_TO_MIXOUTR */
399#define WM9090_IN2A_TO_MIXOUTR_WIDTH 1 /* IN2A_TO_MIXOUTR */
400#define WM9090_IN2B_TO_MIXOUTR 0x0001 /* IN2B_TO_MIXOUTR */
401#define WM9090_IN2B_TO_MIXOUTR_MASK 0x0001 /* IN2B_TO_MIXOUTR */
402#define WM9090_IN2B_TO_MIXOUTR_SHIFT 0 /* IN2B_TO_MIXOUTR */
403#define WM9090_IN2B_TO_MIXOUTR_WIDTH 1 /* IN2B_TO_MIXOUTR */
404
405/*
406 * R47 (0x2F) - Output Mixer3
407 */
408#define WM9090_MIXOUTL_MUTE 0x0100 /* MIXOUTL_MUTE */
409#define WM9090_MIXOUTL_MUTE_MASK 0x0100 /* MIXOUTL_MUTE */
410#define WM9090_MIXOUTL_MUTE_SHIFT 8 /* MIXOUTL_MUTE */
411#define WM9090_MIXOUTL_MUTE_WIDTH 1 /* MIXOUTL_MUTE */
412#define WM9090_IN1A_MIXOUTL_VOL_MASK 0x00C0 /* IN1A_MIXOUTL_VOL - [7:6] */
413#define WM9090_IN1A_MIXOUTL_VOL_SHIFT 6 /* IN1A_MIXOUTL_VOL - [7:6] */
414#define WM9090_IN1A_MIXOUTL_VOL_WIDTH 2 /* IN1A_MIXOUTL_VOL - [7:6] */
415#define WM9090_IN2A_MIXOUTL_VOL_MASK 0x000C /* IN2A_MIXOUTL_VOL - [3:2] */
416#define WM9090_IN2A_MIXOUTL_VOL_SHIFT 2 /* IN2A_MIXOUTL_VOL - [3:2] */
417#define WM9090_IN2A_MIXOUTL_VOL_WIDTH 2 /* IN2A_MIXOUTL_VOL - [3:2] */
418
419/*
420 * R48 (0x30) - Output Mixer4
421 */
422#define WM9090_MIXOUTR_MUTE 0x0100 /* MIXOUTR_MUTE */
423#define WM9090_MIXOUTR_MUTE_MASK 0x0100 /* MIXOUTR_MUTE */
424#define WM9090_MIXOUTR_MUTE_SHIFT 8 /* MIXOUTR_MUTE */
425#define WM9090_MIXOUTR_MUTE_WIDTH 1 /* MIXOUTR_MUTE */
426#define WM9090_IN1A_MIXOUTR_VOL_MASK 0x00C0 /* IN1A_MIXOUTR_VOL - [7:6] */
427#define WM9090_IN1A_MIXOUTR_VOL_SHIFT 6 /* IN1A_MIXOUTR_VOL - [7:6] */
428#define WM9090_IN1A_MIXOUTR_VOL_WIDTH 2 /* IN1A_MIXOUTR_VOL - [7:6] */
429#define WM9090_IN1B_MIXOUTR_VOL_MASK 0x0030 /* IN1B_MIXOUTR_VOL - [5:4] */
430#define WM9090_IN1B_MIXOUTR_VOL_SHIFT 4 /* IN1B_MIXOUTR_VOL - [5:4] */
431#define WM9090_IN1B_MIXOUTR_VOL_WIDTH 2 /* IN1B_MIXOUTR_VOL - [5:4] */
432#define WM9090_IN2A_MIXOUTR_VOL_MASK 0x000C /* IN2A_MIXOUTR_VOL - [3:2] */
433#define WM9090_IN2A_MIXOUTR_VOL_SHIFT 2 /* IN2A_MIXOUTR_VOL - [3:2] */
434#define WM9090_IN2A_MIXOUTR_VOL_WIDTH 2 /* IN2A_MIXOUTR_VOL - [3:2] */
435#define WM9090_IN2B_MIXOUTR_VOL_MASK 0x0003 /* IN2B_MIXOUTR_VOL - [1:0] */
436#define WM9090_IN2B_MIXOUTR_VOL_SHIFT 0 /* IN2B_MIXOUTR_VOL - [1:0] */
437#define WM9090_IN2B_MIXOUTR_VOL_WIDTH 2 /* IN2B_MIXOUTR_VOL - [1:0] */
438
439/*
440 * R54 (0x36) - Speaker Mixer
441 */
442#define WM9090_IN1A_TO_SPKMIX 0x0040 /* IN1A_TO_SPKMIX */
443#define WM9090_IN1A_TO_SPKMIX_MASK 0x0040 /* IN1A_TO_SPKMIX */
444#define WM9090_IN1A_TO_SPKMIX_SHIFT 6 /* IN1A_TO_SPKMIX */
445#define WM9090_IN1A_TO_SPKMIX_WIDTH 1 /* IN1A_TO_SPKMIX */
446#define WM9090_IN1B_TO_SPKMIX 0x0010 /* IN1B_TO_SPKMIX */
447#define WM9090_IN1B_TO_SPKMIX_MASK 0x0010 /* IN1B_TO_SPKMIX */
448#define WM9090_IN1B_TO_SPKMIX_SHIFT 4 /* IN1B_TO_SPKMIX */
449#define WM9090_IN1B_TO_SPKMIX_WIDTH 1 /* IN1B_TO_SPKMIX */
450#define WM9090_IN2A_TO_SPKMIX 0x0004 /* IN2A_TO_SPKMIX */
451#define WM9090_IN2A_TO_SPKMIX_MASK 0x0004 /* IN2A_TO_SPKMIX */
452#define WM9090_IN2A_TO_SPKMIX_SHIFT 2 /* IN2A_TO_SPKMIX */
453#define WM9090_IN2A_TO_SPKMIX_WIDTH 1 /* IN2A_TO_SPKMIX */
454#define WM9090_IN2B_TO_SPKMIX 0x0001 /* IN2B_TO_SPKMIX */
455#define WM9090_IN2B_TO_SPKMIX_MASK 0x0001 /* IN2B_TO_SPKMIX */
456#define WM9090_IN2B_TO_SPKMIX_SHIFT 0 /* IN2B_TO_SPKMIX */
457#define WM9090_IN2B_TO_SPKMIX_WIDTH 1 /* IN2B_TO_SPKMIX */
458
459/*
460 * R57 (0x39) - AntiPOP2
461 */
462#define WM9090_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
463#define WM9090_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
464#define WM9090_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
465#define WM9090_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
466#define WM9090_VMID_ENA 0x0001 /* VMID_ENA */
467#define WM9090_VMID_ENA_MASK 0x0001 /* VMID_ENA */
468#define WM9090_VMID_ENA_SHIFT 0 /* VMID_ENA */
469#define WM9090_VMID_ENA_WIDTH 1 /* VMID_ENA */
470
471/*
472 * R70 (0x46) - Write Sequencer 0
473 */
474#define WM9090_WSEQ_ENA 0x0100 /* WSEQ_ENA */
475#define WM9090_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
476#define WM9090_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
477#define WM9090_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
478#define WM9090_WSEQ_WRITE_INDEX_MASK 0x000F /* WSEQ_WRITE_INDEX - [3:0] */
479#define WM9090_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [3:0] */
480#define WM9090_WSEQ_WRITE_INDEX_WIDTH 4 /* WSEQ_WRITE_INDEX - [3:0] */
481
482/*
483 * R71 (0x47) - Write Sequencer 1
484 */
485#define WM9090_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
486#define WM9090_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
487#define WM9090_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
488#define WM9090_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
489#define WM9090_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
490#define WM9090_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
491#define WM9090_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
492#define WM9090_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
493#define WM9090_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
494
495/*
496 * R72 (0x48) - Write Sequencer 2
497 */
498#define WM9090_WSEQ_EOS 0x4000 /* WSEQ_EOS */
499#define WM9090_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
500#define WM9090_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
501#define WM9090_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
502#define WM9090_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
503#define WM9090_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
504#define WM9090_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
505#define WM9090_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
506#define WM9090_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
507#define WM9090_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
508
509/*
510 * R73 (0x49) - Write Sequencer 3
511 */
512#define WM9090_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
513#define WM9090_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
514#define WM9090_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
515#define WM9090_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
516#define WM9090_WSEQ_START 0x0100 /* WSEQ_START */
517#define WM9090_WSEQ_START_MASK 0x0100 /* WSEQ_START */
518#define WM9090_WSEQ_START_SHIFT 8 /* WSEQ_START */
519#define WM9090_WSEQ_START_WIDTH 1 /* WSEQ_START */
520#define WM9090_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
521#define WM9090_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
522#define WM9090_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
523
524/*
525 * R74 (0x4A) - Write Sequencer 4
526 */
527#define WM9090_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
528#define WM9090_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
529#define WM9090_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
530#define WM9090_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
531
532/*
533 * R75 (0x4B) - Write Sequencer 5
534 */
535#define WM9090_WSEQ_CURRENT_INDEX_MASK 0x003F /* WSEQ_CURRENT_INDEX - [5:0] */
536#define WM9090_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [5:0] */
537#define WM9090_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [5:0] */
538
539/*
540 * R76 (0x4C) - Charge Pump 1
541 */
542#define WM9090_CP_ENA 0x8000 /* CP_ENA */
543#define WM9090_CP_ENA_MASK 0x8000 /* CP_ENA */
544#define WM9090_CP_ENA_SHIFT 15 /* CP_ENA */
545#define WM9090_CP_ENA_WIDTH 1 /* CP_ENA */
546
547/*
548 * R84 (0x54) - DC Servo 0
549 */
550#define WM9090_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
551#define WM9090_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
552#define WM9090_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
553#define WM9090_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
554#define WM9090_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
555#define WM9090_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
556#define WM9090_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
557#define WM9090_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
558#define WM9090_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
559#define WM9090_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
560#define WM9090_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
561#define WM9090_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
562#define WM9090_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
563#define WM9090_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
564#define WM9090_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
565#define WM9090_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
566#define WM9090_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
567#define WM9090_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
568#define WM9090_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
569#define WM9090_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
570#define WM9090_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
571#define WM9090_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
572#define WM9090_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
573#define WM9090_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
574#define WM9090_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
575#define WM9090_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
576#define WM9090_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
577#define WM9090_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
578#define WM9090_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
579#define WM9090_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
580#define WM9090_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
581#define WM9090_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
582#define WM9090_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
583#define WM9090_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
584#define WM9090_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
585#define WM9090_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
586#define WM9090_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
587#define WM9090_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
588#define WM9090_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
589#define WM9090_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
590
591/*
592 * R85 (0x55) - DC Servo 1
593 */
594#define WM9090_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
595#define WM9090_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
596#define WM9090_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
597#define WM9090_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
598#define WM9090_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
599#define WM9090_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
600
601/*
602 * R87 (0x57) - DC Servo 3
603 */
604#define WM9090_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
605#define WM9090_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
606#define WM9090_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
607#define WM9090_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
608#define WM9090_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
609#define WM9090_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
610
611/*
612 * R88 (0x58) - DC Servo Readback 0
613 */
614#define WM9090_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
615#define WM9090_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
616#define WM9090_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
617#define WM9090_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
618#define WM9090_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
619#define WM9090_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
620#define WM9090_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
621#define WM9090_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
622#define WM9090_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
623
624/*
625 * R89 (0x59) - DC Servo Readback 1
626 */
627#define WM9090_DCS_DAC_WR_VAL_1_RD_MASK 0x00FF /* DCS_DAC_WR_VAL_1_RD - [7:0] */
628#define WM9090_DCS_DAC_WR_VAL_1_RD_SHIFT 0 /* DCS_DAC_WR_VAL_1_RD - [7:0] */
629#define WM9090_DCS_DAC_WR_VAL_1_RD_WIDTH 8 /* DCS_DAC_WR_VAL_1_RD - [7:0] */
630
631/*
632 * R90 (0x5A) - DC Servo Readback 2
633 */
634#define WM9090_DCS_DAC_WR_VAL_0_RD_MASK 0x00FF /* DCS_DAC_WR_VAL_0_RD - [7:0] */
635#define WM9090_DCS_DAC_WR_VAL_0_RD_SHIFT 0 /* DCS_DAC_WR_VAL_0_RD - [7:0] */
636#define WM9090_DCS_DAC_WR_VAL_0_RD_WIDTH 8 /* DCS_DAC_WR_VAL_0_RD - [7:0] */
637
638/*
639 * R96 (0x60) - Analogue HP 0
640 */
641#define WM9090_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
642#define WM9090_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
643#define WM9090_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
644#define WM9090_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
645#define WM9090_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
646#define WM9090_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
647#define WM9090_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
648#define WM9090_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
649#define WM9090_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
650#define WM9090_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
651#define WM9090_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
652#define WM9090_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
653#define WM9090_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
654#define WM9090_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
655#define WM9090_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
656#define WM9090_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
657#define WM9090_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
658#define WM9090_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
659#define WM9090_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
660#define WM9090_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
661#define WM9090_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
662#define WM9090_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
663#define WM9090_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
664#define WM9090_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
665
666/*
667 * R98 (0x62) - AGC Control 0
668 */
669#define WM9090_AGC_CLIP_ENA 0x8000 /* AGC_CLIP_ENA */
670#define WM9090_AGC_CLIP_ENA_MASK 0x8000 /* AGC_CLIP_ENA */
671#define WM9090_AGC_CLIP_ENA_SHIFT 15 /* AGC_CLIP_ENA */
672#define WM9090_AGC_CLIP_ENA_WIDTH 1 /* AGC_CLIP_ENA */
673#define WM9090_AGC_CLIP_THR_MASK 0x0F00 /* AGC_CLIP_THR - [11:8] */
674#define WM9090_AGC_CLIP_THR_SHIFT 8 /* AGC_CLIP_THR - [11:8] */
675#define WM9090_AGC_CLIP_THR_WIDTH 4 /* AGC_CLIP_THR - [11:8] */
676#define WM9090_AGC_CLIP_ATK_MASK 0x0070 /* AGC_CLIP_ATK - [6:4] */
677#define WM9090_AGC_CLIP_ATK_SHIFT 4 /* AGC_CLIP_ATK - [6:4] */
678#define WM9090_AGC_CLIP_ATK_WIDTH 3 /* AGC_CLIP_ATK - [6:4] */
679#define WM9090_AGC_CLIP_DCY_MASK 0x0007 /* AGC_CLIP_DCY - [2:0] */
680#define WM9090_AGC_CLIP_DCY_SHIFT 0 /* AGC_CLIP_DCY - [2:0] */
681#define WM9090_AGC_CLIP_DCY_WIDTH 3 /* AGC_CLIP_DCY - [2:0] */
682
683/*
684 * R99 (0x63) - AGC Control 1
685 */
686#define WM9090_AGC_PWR_ENA 0x8000 /* AGC_PWR_ENA */
687#define WM9090_AGC_PWR_ENA_MASK 0x8000 /* AGC_PWR_ENA */
688#define WM9090_AGC_PWR_ENA_SHIFT 15 /* AGC_PWR_ENA */
689#define WM9090_AGC_PWR_ENA_WIDTH 1 /* AGC_PWR_ENA */
690#define WM9090_AGC_PWR_AVG 0x1000 /* AGC_PWR_AVG */
691#define WM9090_AGC_PWR_AVG_MASK 0x1000 /* AGC_PWR_AVG */
692#define WM9090_AGC_PWR_AVG_SHIFT 12 /* AGC_PWR_AVG */
693#define WM9090_AGC_PWR_AVG_WIDTH 1 /* AGC_PWR_AVG */
694#define WM9090_AGC_PWR_THR_MASK 0x0F00 /* AGC_PWR_THR - [11:8] */
695#define WM9090_AGC_PWR_THR_SHIFT 8 /* AGC_PWR_THR - [11:8] */
696#define WM9090_AGC_PWR_THR_WIDTH 4 /* AGC_PWR_THR - [11:8] */
697#define WM9090_AGC_PWR_ATK_MASK 0x0070 /* AGC_PWR_ATK - [6:4] */
698#define WM9090_AGC_PWR_ATK_SHIFT 4 /* AGC_PWR_ATK - [6:4] */
699#define WM9090_AGC_PWR_ATK_WIDTH 3 /* AGC_PWR_ATK - [6:4] */
700#define WM9090_AGC_PWR_DCY_MASK 0x0007 /* AGC_PWR_DCY - [2:0] */
701#define WM9090_AGC_PWR_DCY_SHIFT 0 /* AGC_PWR_DCY - [2:0] */
702#define WM9090_AGC_PWR_DCY_WIDTH 3 /* AGC_PWR_DCY - [2:0] */
703
704/*
705 * R100 (0x64) - AGC Control 2
706 */
707#define WM9090_AGC_RAMP 0x0100 /* AGC_RAMP */
708#define WM9090_AGC_RAMP_MASK 0x0100 /* AGC_RAMP */
709#define WM9090_AGC_RAMP_SHIFT 8 /* AGC_RAMP */
710#define WM9090_AGC_RAMP_WIDTH 1 /* AGC_RAMP */
711#define WM9090_AGC_MINGAIN_MASK 0x003F /* AGC_MINGAIN - [5:0] */
712#define WM9090_AGC_MINGAIN_SHIFT 0 /* AGC_MINGAIN - [5:0] */
713#define WM9090_AGC_MINGAIN_WIDTH 6 /* AGC_MINGAIN - [5:0] */
714
715#endif
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 2f48a8aae22c..28790a2ffe8d 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -632,9 +632,6 @@ static int wm9712_soc_resume(struct platform_device *pdev)
632 } 632 }
633 } 633 }
634 634
635 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
636 wm9712_set_bias_level(codec, SND_SOC_BIAS_ON);
637
638 return ret; 635 return ret;
639} 636}
640 637
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 2fca514fde58..34e0c91092fa 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -764,7 +764,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source)
764static int wm9713_set_pll(struct snd_soc_codec *codec, 764static int wm9713_set_pll(struct snd_soc_codec *codec,
765 int pll_id, unsigned int freq_in, unsigned int freq_out) 765 int pll_id, unsigned int freq_in, unsigned int freq_out)
766{ 766{
767 struct wm9713_priv *wm9713 = codec->private_data; 767 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
768 u16 reg, reg2; 768 u16 reg, reg2;
769 struct _pll_div pll_div; 769 struct _pll_div pll_div;
770 770
@@ -1175,7 +1175,7 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1175{ 1175{
1176 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1176 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1177 struct snd_soc_codec *codec = socdev->card->codec; 1177 struct snd_soc_codec *codec = socdev->card->codec;
1178 struct wm9713_priv *wm9713 = codec->private_data; 1178 struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
1179 int i, ret; 1179 int i, ret;
1180 u16 *cache = codec->reg_cache; 1180 u16 *cache = codec->reg_cache;
1181 1181
@@ -1201,9 +1201,6 @@ static int wm9713_soc_resume(struct platform_device *pdev)
1201 } 1201 }
1202 } 1202 }
1203 1203
1204 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1205 wm9713_set_bias_level(codec, SND_SOC_BIAS_ON);
1206
1207 return ret; 1204 return ret;
1208} 1205}
1209 1206
@@ -1228,8 +1225,9 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1228 codec->reg_cache_size = sizeof(wm9713_reg); 1225 codec->reg_cache_size = sizeof(wm9713_reg);
1229 codec->reg_cache_step = 2; 1226 codec->reg_cache_step = 2;
1230 1227
1231 codec->private_data = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL); 1228 snd_soc_codec_set_drvdata(codec, kzalloc(sizeof(struct wm9713_priv),
1232 if (codec->private_data == NULL) { 1229 GFP_KERNEL));
1230 if (snd_soc_codec_get_drvdata(codec) == NULL) {
1233 ret = -ENOMEM; 1231 ret = -ENOMEM;
1234 goto priv_err; 1232 goto priv_err;
1235 } 1233 }
@@ -1280,7 +1278,7 @@ pcm_err:
1280 snd_soc_free_ac97_codec(codec); 1278 snd_soc_free_ac97_codec(codec);
1281 1279
1282codec_err: 1280codec_err:
1283 kfree(codec->private_data); 1281 kfree(snd_soc_codec_get_drvdata(codec));
1284 1282
1285priv_err: 1283priv_err:
1286 kfree(codec->reg_cache); 1284 kfree(codec->reg_cache);
@@ -1302,7 +1300,7 @@ static int wm9713_soc_remove(struct platform_device *pdev)
1302 snd_soc_dapm_free(socdev); 1300 snd_soc_dapm_free(socdev);
1303 snd_soc_free_pcms(socdev); 1301 snd_soc_free_pcms(socdev);
1304 snd_soc_free_ac97_codec(codec); 1302 snd_soc_free_ac97_codec(codec);
1305 kfree(codec->private_data); 1303 kfree(snd_soc_codec_get_drvdata(codec));
1306 kfree(codec->reg_cache); 1304 kfree(codec->reg_cache);
1307 kfree(codec); 1305 kfree(codec);
1308 return 0; 1306 return 0;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e1f225a3ac46..16f1a57da08a 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -91,7 +91,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
91 */ 91 */
92static void calibrate_dc_servo(struct snd_soc_codec *codec) 92static void calibrate_dc_servo(struct snd_soc_codec *codec)
93{ 93{
94 struct wm_hubs_data *hubs = codec->private_data; 94 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
95 u16 reg, reg_l, reg_r, dcs_cfg; 95 u16 reg, reg_l, reg_r, dcs_cfg;
96 96
97 /* Set for 32 series updates */ 97 /* Set for 32 series updates */
@@ -127,6 +127,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
127 break; 127 break;
128 } 128 }
129 129
130 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
131
130 /* HPOUT1L */ 132 /* HPOUT1L */
131 if (reg_l + hubs->dcs_codes > 0 && 133 if (reg_l + hubs->dcs_codes > 0 &&
132 reg_l + hubs->dcs_codes < 0xff) 134 reg_l + hubs->dcs_codes < 0xff)
@@ -139,6 +141,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
139 reg_r += hubs->dcs_codes; 141 reg_r += hubs->dcs_codes;
140 dcs_cfg |= reg_r; 142 dcs_cfg |= reg_r;
141 143
144 dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
145
142 /* Do it */ 146 /* Do it */
143 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); 147 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
144 wait_for_dc_servo(codec, 148 wait_for_dc_servo(codec,
@@ -154,7 +158,7 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
154 struct snd_ctl_elem_value *ucontrol) 158 struct snd_ctl_elem_value *ucontrol)
155{ 159{
156 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 160 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
157 struct wm_hubs_data *hubs = codec->private_data; 161 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
158 int ret; 162 int ret;
159 163
160 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 164 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
@@ -327,7 +331,7 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w,
327 struct snd_kcontrol *kcontrol, int event) 331 struct snd_kcontrol *kcontrol, int event)
328{ 332{
329 struct snd_soc_codec *codec = w->codec; 333 struct snd_soc_codec *codec = w->codec;
330 struct wm_hubs_data *hubs = codec->private_data; 334 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
331 335
332 switch (event) { 336 switch (event) {
333 case SND_SOC_DAPM_PRE_PMU: 337 case SND_SOC_DAPM_PRE_PMU:
@@ -397,14 +401,14 @@ static int hp_event(struct snd_soc_dapm_widget *w,
397 401
398 case SND_SOC_DAPM_PRE_PMD: 402 case SND_SOC_DAPM_PRE_PMD:
399 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0, 403 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
400 WM8993_HPOUT1L_DLY | 404 WM8993_HPOUT1L_OUTP |
401 WM8993_HPOUT1R_DLY | 405 WM8993_HPOUT1R_OUTP |
402 WM8993_HPOUT1L_RMV_SHORT | 406 WM8993_HPOUT1L_RMV_SHORT |
403 WM8993_HPOUT1R_RMV_SHORT, 0); 407 WM8993_HPOUT1R_RMV_SHORT, 0);
404 408
405 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0, 409 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
406 WM8993_HPOUT1L_OUTP | 410 WM8993_HPOUT1L_DLY |
407 WM8993_HPOUT1R_OUTP, 0); 411 WM8993_HPOUT1R_DLY, 0);
408 412
409 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 413 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
410 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 414 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 047ee39418c0..6bbf001f6591 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -12,15 +12,38 @@ config SND_DAVINCI_SOC_I2S
12config SND_DAVINCI_SOC_MCASP 12config SND_DAVINCI_SOC_MCASP
13 tristate 13 tristate
14 14
15config SND_DAVINCI_SOC_VCIF
16 tristate
17
15config SND_DAVINCI_SOC_EVM 18config SND_DAVINCI_SOC_EVM
16 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" 19 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
17 depends on SND_DAVINCI_SOC 20 depends on SND_DAVINCI_SOC
18 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM 21 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
19 select SND_DAVINCI_SOC_I2S 22 select SND_DAVINCI_SOC_I2S
20 select SND_SOC_TLV320AIC3X 23 select SND_SOC_TLV320AIC3X
21 help 24 help
22 Say Y if you want to add support for SoC audio on TI 25 Say Y if you want to add support for SoC audio on TI
23 DaVinci DM6446 or DM355 EVM platforms. 26 DaVinci DM6446, DM355 or DM365 EVM platforms.
27
28choice
29 prompt "DM365 codec select"
30 depends on SND_DAVINCI_SOC_EVM
31 depends on MACH_DAVINCI_DM365_EVM
32 default SND_DM365_EXTERNAL_CODEC
33
34config SND_DM365_AIC3X_CODEC
35 bool "Audio Codec - AIC3101"
36 help
37 Say Y if you want to add support for AIC3101 audio codec
38
39config SND_DM365_VOICE_CODEC
40 bool "Voice Codec - CQ93VC"
41 select MFD_DAVINCI_VOICECODEC
42 select SND_DAVINCI_SOC_VCIF
43 select SND_SOC_CQ0093VC
44 help
45 Say Y if you want to add support for SoC On-chip voice codec
46endchoice
24 47
25config SND_DM6467_SOC_EVM 48config SND_DM6467_SOC_EVM
26 tristate "SoC Audio support for DaVinci DM6467 EVM" 49 tristate "SoC Audio support for DaVinci DM6467 EVM"
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index a6939d71b988..a93679d618cd 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -2,10 +2,12 @@
2snd-soc-davinci-objs := davinci-pcm.o 2snd-soc-davinci-objs := davinci-pcm.o
3snd-soc-davinci-i2s-objs := davinci-i2s.o 3snd-soc-davinci-i2s-objs := davinci-i2s.o
4snd-soc-davinci-mcasp-objs:= davinci-mcasp.o 4snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
5snd-soc-davinci-vcif-objs:= davinci-vcif.o
5 6
6obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o 7obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o
7obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o 8obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
8obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o 9obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
10obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
9 11
10# DAVINCI Machine Support 12# DAVINCI Machine Support
11snd-soc-evm-objs := davinci-evm.o 13snd-soc-evm-objs := davinci-evm.o
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 7ccbe6684fc2..97f74d6a33e6 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -28,10 +28,12 @@
28#include <mach/mux.h> 28#include <mach/mux.h>
29 29
30#include "../codecs/tlv320aic3x.h" 30#include "../codecs/tlv320aic3x.h"
31#include "../codecs/cq93vc.h"
31#include "../codecs/spdif_transciever.h" 32#include "../codecs/spdif_transciever.h"
32#include "davinci-pcm.h" 33#include "davinci-pcm.h"
33#include "davinci-i2s.h" 34#include "davinci-i2s.h"
34#include "davinci-mcasp.h" 35#include "davinci-mcasp.h"
36#include "davinci-vcif.h"
35 37
36#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ 38#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
37 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) 39 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
@@ -81,10 +83,24 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
81 return 0; 83 return 0;
82} 84}
83 85
86static int evm_spdif_hw_params(struct snd_pcm_substream *substream,
87 struct snd_pcm_hw_params *params)
88{
89 struct snd_soc_pcm_runtime *rtd = substream->private_data;
90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
91
92 /* set cpu DAI configuration */
93 return snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
94}
95
84static struct snd_soc_ops evm_ops = { 96static struct snd_soc_ops evm_ops = {
85 .hw_params = evm_hw_params, 97 .hw_params = evm_hw_params,
86}; 98};
87 99
100static struct snd_soc_ops evm_spdif_ops = {
101 .hw_params = evm_spdif_hw_params,
102};
103
88/* davinci-evm machine dapm widgets */ 104/* davinci-evm machine dapm widgets */
89static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { 105static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
90 SND_SOC_DAPM_HP("Headphone Jack", NULL), 106 SND_SOC_DAPM_HP("Headphone Jack", NULL),
@@ -151,6 +167,22 @@ static struct snd_soc_dai_link evm_dai = {
151 .ops = &evm_ops, 167 .ops = &evm_ops,
152}; 168};
153 169
170static struct snd_soc_dai_link dm365_evm_dai = {
171#ifdef CONFIG_SND_DM365_AIC3X_CODEC
172 .name = "TLV320AIC3X",
173 .stream_name = "AIC3X",
174 .cpu_dai = &davinci_i2s_dai,
175 .codec_dai = &aic3x_dai,
176 .init = evm_aic3x_init,
177 .ops = &evm_ops,
178#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
179 .name = "Voice Codec - CQ93VC",
180 .stream_name = "CQ93",
181 .cpu_dai = &davinci_vcif_dai,
182 .codec_dai = &cq93vc_dai,
183#endif
184};
185
154static struct snd_soc_dai_link dm6467_evm_dai[] = { 186static struct snd_soc_dai_link dm6467_evm_dai[] = {
155 { 187 {
156 .name = "TLV320AIC3X", 188 .name = "TLV320AIC3X",
@@ -165,7 +197,7 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = {
165 .stream_name = "spdif", 197 .stream_name = "spdif",
166 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_DIT_DAI], 198 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_DIT_DAI],
167 .codec_dai = &dit_stub_dai, 199 .codec_dai = &dit_stub_dai,
168 .ops = &evm_ops, 200 .ops = &evm_spdif_ops,
169 }, 201 },
170}; 202};
171static struct snd_soc_dai_link da8xx_evm_dai = { 203static struct snd_soc_dai_link da8xx_evm_dai = {
@@ -177,7 +209,7 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
177 .ops = &evm_ops, 209 .ops = &evm_ops,
178}; 210};
179 211
180/* davinci dm6446, dm355 or dm365 evm audio machine driver */ 212/* davinci dm6446, dm355 evm audio machine driver */
181static struct snd_soc_card snd_soc_card_evm = { 213static struct snd_soc_card snd_soc_card_evm = {
182 .name = "DaVinci EVM", 214 .name = "DaVinci EVM",
183 .platform = &davinci_soc_platform, 215 .platform = &davinci_soc_platform,
@@ -185,6 +217,15 @@ static struct snd_soc_card snd_soc_card_evm = {
185 .num_links = 1, 217 .num_links = 1,
186}; 218};
187 219
220/* davinci dm365 evm audio machine driver */
221static struct snd_soc_card dm365_snd_soc_card_evm = {
222 .name = "DaVinci DM365 EVM",
223 .platform = &davinci_soc_platform,
224 .dai_link = &dm365_evm_dai,
225 .num_links = 1,
226};
227
228
188/* davinci dm6467 evm audio machine driver */ 229/* davinci dm6467 evm audio machine driver */
189static struct snd_soc_card dm6467_snd_soc_card_evm = { 230static struct snd_soc_card dm6467_snd_soc_card_evm = {
190 .name = "DaVinci DM6467 EVM", 231 .name = "DaVinci DM6467 EVM",
@@ -217,6 +258,17 @@ static struct snd_soc_device evm_snd_devdata = {
217}; 258};
218 259
219/* evm audio subsystem */ 260/* evm audio subsystem */
261static struct snd_soc_device dm365_evm_snd_devdata = {
262 .card = &dm365_snd_soc_card_evm,
263#ifdef CONFIG_SND_DM365_AIC3X_CODEC
264 .codec_dev = &soc_codec_dev_aic3x,
265 .codec_data = &aic3x_setup,
266#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
267 .codec_dev = &soc_codec_dev_cq93vc,
268#endif
269};
270
271/* evm audio subsystem */
220static struct snd_soc_device dm6467_evm_snd_devdata = { 272static struct snd_soc_device dm6467_evm_snd_devdata = {
221 .card = &dm6467_snd_soc_card_evm, 273 .card = &dm6467_snd_soc_card_evm,
222 .codec_dev = &soc_codec_dev_aic3x, 274 .codec_dev = &soc_codec_dev_aic3x,
@@ -244,12 +296,15 @@ static int __init evm_init(void)
244 int index; 296 int index;
245 int ret; 297 int ret;
246 298
247 if (machine_is_davinci_evm() || machine_is_davinci_dm365_evm()) { 299 if (machine_is_davinci_evm()) {
248 evm_snd_dev_data = &evm_snd_devdata; 300 evm_snd_dev_data = &evm_snd_devdata;
249 index = 0; 301 index = 0;
250 } else if (machine_is_davinci_dm355_evm()) { 302 } else if (machine_is_davinci_dm355_evm()) {
251 evm_snd_dev_data = &evm_snd_devdata; 303 evm_snd_dev_data = &evm_snd_devdata;
252 index = 1; 304 index = 1;
305 } else if (machine_is_davinci_dm365_evm()) {
306 evm_snd_dev_data = &dm365_evm_snd_devdata;
307 index = 0;
253 } else if (machine_is_davinci_dm6467_evm()) { 308 } else if (machine_is_davinci_dm6467_evm()) {
254 evm_snd_dev_data = &dm6467_evm_snd_devdata; 309 evm_snd_dev_data = &dm6467_evm_snd_devdata;
255 index = 0; 310 index = 0;
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
new file mode 100644
index 000000000000..9aa980d38231
--- /dev/null
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -0,0 +1,274 @@
1/*
2 * ALSA SoC Voice Codec Interface for TI DAVINCI processor
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/device.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/io.h>
29#include <linux/mfd/davinci_voicecodec.h>
30
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/initval.h>
35#include <sound/soc.h>
36
37#include "davinci-pcm.h"
38#include "davinci-i2s.h"
39#include "davinci-vcif.h"
40
41#define MOD_REG_BIT(val, mask, set) do { \
42 if (set) { \
43 val |= mask; \
44 } else { \
45 val &= ~mask; \
46 } \
47} while (0)
48
49struct davinci_vcif_dev {
50 struct davinci_vc *davinci_vc;
51 struct davinci_pcm_dma_params dma_params[2];
52};
53
54static void davinci_vcif_start(struct snd_pcm_substream *substream)
55{
56 struct snd_soc_pcm_runtime *rtd = substream->private_data;
57 struct davinci_vcif_dev *davinci_vcif_dev =
58 rtd->dai->cpu_dai->private_data;
59 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
60 u32 w;
61
62 /* Start the sample generator and enable transmitter/receiver */
63 w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
64
65 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
66 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1);
67 else
68 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1);
69
70 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
71}
72
73static void davinci_vcif_stop(struct snd_pcm_substream *substream)
74{
75 struct snd_soc_pcm_runtime *rtd = substream->private_data;
76 struct davinci_vcif_dev *davinci_vcif_dev =
77 rtd->dai->cpu_dai->private_data;
78 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
79 u32 w;
80
81 /* Reset transmitter/receiver and sample rate/frame sync generators */
82 w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
83 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
84 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0);
85 else
86 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0);
87
88 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
89}
90
91static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
92 struct snd_pcm_hw_params *params,
93 struct snd_soc_dai *dai)
94{
95 struct davinci_vcif_dev *davinci_vcif_dev = dai->private_data;
96 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
97 struct davinci_pcm_dma_params *dma_params =
98 &davinci_vcif_dev->dma_params[substream->stream];
99 u32 w;
100
101 /* Restart the codec before setup */
102 davinci_vcif_stop(substream);
103 davinci_vcif_start(substream);
104
105 /* General line settings */
106 writel(DAVINCI_VC_CTRL_MASK, davinci_vc->base + DAVINCI_VC_CTRL);
107
108 writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTCLR);
109
110 writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTEN);
111
112 w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
113
114 /* Determine xfer data type */
115 switch (params_format(params)) {
116 case SNDRV_PCM_FORMAT_U8:
117 dma_params->data_type = 0;
118
119 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
120 DAVINCI_VC_CTRL_RD_UNSIGNED |
121 DAVINCI_VC_CTRL_WD_BITS_8 |
122 DAVINCI_VC_CTRL_WD_UNSIGNED, 1);
123 break;
124 case SNDRV_PCM_FORMAT_S8:
125 dma_params->data_type = 1;
126
127 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
128 DAVINCI_VC_CTRL_WD_BITS_8, 1);
129
130 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_UNSIGNED |
131 DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
132 break;
133 case SNDRV_PCM_FORMAT_S16_LE:
134 dma_params->data_type = 2;
135
136 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
137 DAVINCI_VC_CTRL_RD_UNSIGNED |
138 DAVINCI_VC_CTRL_WD_BITS_8 |
139 DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
140 break;
141 default:
142 printk(KERN_WARNING "davinci-vcif: unsupported PCM format");
143 return -EINVAL;
144 }
145
146 dma_params->acnt = dma_params->data_type;
147
148 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
149
150 return 0;
151}
152
153static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
154 struct snd_soc_dai *dai)
155{
156 int ret = 0;
157
158 switch (cmd) {
159 case SNDRV_PCM_TRIGGER_START:
160 case SNDRV_PCM_TRIGGER_RESUME:
161 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
162 davinci_vcif_start(substream);
163 case SNDRV_PCM_TRIGGER_STOP:
164 case SNDRV_PCM_TRIGGER_SUSPEND:
165 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
166 davinci_vcif_stop(substream);
167 break;
168 default:
169 ret = -EINVAL;
170 }
171
172 return ret;
173}
174
175#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
176
177static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
178 .trigger = davinci_vcif_trigger,
179 .hw_params = davinci_vcif_hw_params,
180};
181
182struct snd_soc_dai davinci_vcif_dai = {
183 .name = "davinci-vcif",
184 .playback = {
185 .channels_min = 1,
186 .channels_max = 2,
187 .rates = DAVINCI_VCIF_RATES,
188 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
189 .capture = {
190 .channels_min = 1,
191 .channels_max = 2,
192 .rates = DAVINCI_VCIF_RATES,
193 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
194 .ops = &davinci_vcif_dai_ops,
195
196};
197EXPORT_SYMBOL_GPL(davinci_vcif_dai);
198
199static int davinci_vcif_probe(struct platform_device *pdev)
200{
201 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev);
202 struct davinci_vcif_dev *davinci_vcif_dev;
203 int ret;
204
205 davinci_vcif_dev = kzalloc(sizeof(struct davinci_vcif_dev), GFP_KERNEL);
206 if (!davinci_vc) {
207 dev_dbg(&pdev->dev,
208 "could not allocate memory for private data\n");
209 return -ENOMEM;
210 }
211
212 /* DMA tx params */
213 davinci_vcif_dev->davinci_vc = davinci_vc;
214 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel =
215 davinci_vc->davinci_vcif.dma_tx_channel;
216 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
217 davinci_vc->davinci_vcif.dma_tx_addr;
218
219 /* DMA rx params */
220 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel =
221 davinci_vc->davinci_vcif.dma_rx_channel;
222 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
223 davinci_vc->davinci_vcif.dma_rx_addr;
224
225 davinci_vcif_dai.dev = &pdev->dev;
226 davinci_vcif_dai.capture.dma_data = davinci_vcif_dev->dma_params;
227 davinci_vcif_dai.playback.dma_data = davinci_vcif_dev->dma_params;
228 davinci_vcif_dai.private_data = davinci_vcif_dev;
229
230 ret = snd_soc_register_dai(&davinci_vcif_dai);
231 if (ret != 0) {
232 dev_err(&pdev->dev, "could not register dai\n");
233 goto fail;
234 }
235
236 return 0;
237
238fail:
239 kfree(davinci_vcif_dev);
240
241 return ret;
242}
243
244static int davinci_vcif_remove(struct platform_device *pdev)
245{
246 snd_soc_unregister_dai(&davinci_vcif_dai);
247
248 return 0;
249}
250
251static struct platform_driver davinci_vcif_driver = {
252 .probe = davinci_vcif_probe,
253 .remove = davinci_vcif_remove,
254 .driver = {
255 .name = "davinci_vcif",
256 .owner = THIS_MODULE,
257 },
258};
259
260static int __init davinci_vcif_init(void)
261{
262 return platform_driver_probe(&davinci_vcif_driver, davinci_vcif_probe);
263}
264module_init(davinci_vcif_init);
265
266static void __exit davinci_vcif_exit(void)
267{
268 platform_driver_unregister(&davinci_vcif_driver);
269}
270module_exit(davinci_vcif_exit);
271
272MODULE_AUTHOR("Miguel Aguilar");
273MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface");
274MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-vcif.h b/sound/soc/davinci/davinci-vcif.h
new file mode 100644
index 000000000000..571c9948724f
--- /dev/null
+++ b/sound/soc/davinci/davinci-vcif.h
@@ -0,0 +1,28 @@
1/*
2 * ALSA SoC Voice Codec Interface for TI DAVINCI processor
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _DAVINCI_VCIF_H
24#define _DAVINCI_VCIF_H
25
26extern struct snd_soc_dai davinci_vcif_dai;
27
28#endif
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 7174b4c710de..eba9b9d257a1 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -11,3 +11,11 @@ config SND_IMX_SOC
11config SND_MXC_SOC_SSI 11config SND_MXC_SOC_SSI
12 tristate 12 tristate
13 13
14config SND_MXC_SOC_WM1133_EV1
15 tristate "Audio on the the i.MX31ADS with WM1133-EV1 fitted"
16 depends on SND_IMX_SOC && EXPERIMENTAL
17 select SND_SOC_WM8350
18 select SND_MXC_SOC_SSI
19 help
20 Enable support for audio on the i.MX31ADS with the WM1133-EV1
21 PMIC board with WM8835x fitted.
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index 9f8bb92ddfcc..2d203635ac11 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -9,4 +9,7 @@ obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
9 9
10# i.MX Machine Support 10# i.MX Machine Support
11snd-soc-phycore-ac97-objs := phycore-ac97.o 11snd-soc-phycore-ac97-objs := phycore-ac97.o
12snd-soc-wm1133-ev1-objs := wm1133-ev1.o
13
12obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o 14obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
15obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
new file mode 100644
index 000000000000..a6e7d9497639
--- /dev/null
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -0,0 +1,308 @@
1/*
2 * wm1133-ev1.c - Audio for WM1133-EV1 on i.MX31ADS
3 *
4 * Copyright (c) 2010 Wolfson Microelectronics plc
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * Based on an earlier driver for the same hardware by Liam Girdwood.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/platform_device.h>
16#include <linux/clk.h>
17#include <sound/core.h>
18#include <sound/jack.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24#include <mach/audmux.h>
25
26#include "imx-ssi.h"
27#include "../codecs/wm8350.h"
28
29/* There is a silicon mic on the board optionally connected via a solder pad
30 * SP1. Define this to enable it.
31 */
32#undef USE_SIMIC
33
34struct _wm8350_audio {
35 unsigned int channels;
36 snd_pcm_format_t format;
37 unsigned int rate;
38 unsigned int sysclk;
39 unsigned int bclkdiv;
40 unsigned int clkdiv;
41 unsigned int lr_rate;
42};
43
44/* in order of power consumption per rate (lowest first) */
45static const struct _wm8350_audio wm8350_audio[] = {
46 /* 16bit mono modes */
47 {1, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000 >> 1,
48 WM8350_BCLK_DIV_48, WM8350_DACDIV_3, 16,},
49
50 /* 16 bit stereo modes */
51 {2, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000,
52 WM8350_BCLK_DIV_48, WM8350_DACDIV_6, 32,},
53 {2, SNDRV_PCM_FORMAT_S16_LE, 16000, 12288000,
54 WM8350_BCLK_DIV_24, WM8350_DACDIV_3, 32,},
55 {2, SNDRV_PCM_FORMAT_S16_LE, 32000, 12288000,
56 WM8350_BCLK_DIV_12, WM8350_DACDIV_1_5, 32,},
57 {2, SNDRV_PCM_FORMAT_S16_LE, 48000, 12288000,
58 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
59 {2, SNDRV_PCM_FORMAT_S16_LE, 96000, 24576000,
60 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
61 {2, SNDRV_PCM_FORMAT_S16_LE, 11025, 11289600,
62 WM8350_BCLK_DIV_32, WM8350_DACDIV_4, 32,},
63 {2, SNDRV_PCM_FORMAT_S16_LE, 22050, 11289600,
64 WM8350_BCLK_DIV_16, WM8350_DACDIV_2, 32,},
65 {2, SNDRV_PCM_FORMAT_S16_LE, 44100, 11289600,
66 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
67 {2, SNDRV_PCM_FORMAT_S16_LE, 88200, 22579200,
68 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
69
70 /* 24bit stereo modes */
71 {2, SNDRV_PCM_FORMAT_S24_LE, 48000, 12288000,
72 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
73 {2, SNDRV_PCM_FORMAT_S24_LE, 96000, 24576000,
74 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
75 {2, SNDRV_PCM_FORMAT_S24_LE, 44100, 11289600,
76 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
77 {2, SNDRV_PCM_FORMAT_S24_LE, 88200, 22579200,
78 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
79};
80
81static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream,
82 struct snd_pcm_hw_params *params)
83{
84 struct snd_soc_pcm_runtime *rtd = substream->private_data;
85 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
86 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
87 int i, found = 0;
88 snd_pcm_format_t format = params_format(params);
89 unsigned int rate = params_rate(params);
90 unsigned int channels = params_channels(params);
91 u32 dai_format;
92
93 /* find the correct audio parameters */
94 for (i = 0; i < ARRAY_SIZE(wm8350_audio); i++) {
95 if (rate == wm8350_audio[i].rate &&
96 format == wm8350_audio[i].format &&
97 channels == wm8350_audio[i].channels) {
98 found = 1;
99 break;
100 }
101 }
102 if (!found)
103 return -EINVAL;
104
105 /* codec FLL input is 14.75 MHz from MCLK */
106 snd_soc_dai_set_pll(codec_dai, 0, 0, 14750000, wm8350_audio[i].sysclk);
107
108 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
109 SND_SOC_DAIFMT_CBM_CFM;
110
111 /* set codec DAI configuration */
112 snd_soc_dai_set_fmt(codec_dai, dai_format);
113
114 /* set cpu DAI configuration */
115 snd_soc_dai_set_fmt(cpu_dai, dai_format);
116
117 /* TODO: The SSI driver should figure this out for us */
118 switch (channels) {
119 case 2:
120 snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
121 break;
122 case 1:
123 snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffe, 0xffffffe, 1, 0);
124 break;
125 default:
126 return -EINVAL;
127 }
128
129 /* set MCLK as the codec system clock for DAC and ADC */
130 snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_MCLK,
131 wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
132
133 /* set codec BCLK division for sample rate */
134 snd_soc_dai_set_clkdiv(codec_dai, WM8350_BCLK_CLKDIV,
135 wm8350_audio[i].bclkdiv);
136
137 /* DAI is synchronous and clocked with DAC LRCLK & ADC LRC */
138 snd_soc_dai_set_clkdiv(codec_dai,
139 WM8350_DACLR_CLKDIV, wm8350_audio[i].lr_rate);
140 snd_soc_dai_set_clkdiv(codec_dai,
141 WM8350_ADCLR_CLKDIV, wm8350_audio[i].lr_rate);
142
143 /* now configure DAC and ADC clocks */
144 snd_soc_dai_set_clkdiv(codec_dai,
145 WM8350_DAC_CLKDIV, wm8350_audio[i].clkdiv);
146
147 snd_soc_dai_set_clkdiv(codec_dai,
148 WM8350_ADC_CLKDIV, wm8350_audio[i].clkdiv);
149
150 return 0;
151}
152
153static struct snd_soc_ops wm1133_ev1_ops = {
154 .hw_params = wm1133_ev1_hw_params,
155};
156
157static const struct snd_soc_dapm_widget wm1133_ev1_widgets[] = {
158#ifdef USE_SIMIC
159 SND_SOC_DAPM_MIC("SiMIC", NULL),
160#endif
161 SND_SOC_DAPM_MIC("Mic1 Jack", NULL),
162 SND_SOC_DAPM_MIC("Mic2 Jack", NULL),
163 SND_SOC_DAPM_LINE("Line In Jack", NULL),
164 SND_SOC_DAPM_LINE("Line Out Jack", NULL),
165 SND_SOC_DAPM_HP("Headphone Jack", NULL),
166};
167
168/* imx32ads soc_card audio map */
169static const struct snd_soc_dapm_route wm1133_ev1_map[] = {
170
171#ifdef USE_SIMIC
172 /* SiMIC --> IN1LN (with automatic bias) via SP1 */
173 { "IN1LN", NULL, "Mic Bias" },
174 { "Mic Bias", NULL, "SiMIC" },
175#endif
176
177 /* Mic 1 Jack --> IN1LN and IN1LP (with automatic bias) */
178 { "IN1LN", NULL, "Mic Bias" },
179 { "IN1LP", NULL, "Mic1 Jack" },
180 { "Mic Bias", NULL, "Mic1 Jack" },
181
182 /* Mic 2 Jack --> IN1RN and IN1RP (with automatic bias) */
183 { "IN1RN", NULL, "Mic Bias" },
184 { "IN1RP", NULL, "Mic2 Jack" },
185 { "Mic Bias", NULL, "Mic2 Jack" },
186
187 /* Line in Jack --> AUX (L+R) */
188 { "IN3R", NULL, "Line In Jack" },
189 { "IN3L", NULL, "Line In Jack" },
190
191 /* Out1 --> Headphone Jack */
192 { "Headphone Jack", NULL, "OUT1R" },
193 { "Headphone Jack", NULL, "OUT1L" },
194
195 /* Out1 --> Line Out Jack */
196 { "Line Out Jack", NULL, "OUT2R" },
197 { "Line Out Jack", NULL, "OUT2L" },
198};
199
200static struct snd_soc_jack hp_jack;
201
202static struct snd_soc_jack_pin hp_jack_pins[] = {
203 { .pin = "Headphone Jack", .mask = SND_JACK_HEADPHONE },
204};
205
206static struct snd_soc_jack mic_jack;
207
208static struct snd_soc_jack_pin mic_jack_pins[] = {
209 { .pin = "Mic1 Jack", .mask = SND_JACK_MICROPHONE },
210 { .pin = "Mic2 Jack", .mask = SND_JACK_MICROPHONE },
211};
212
213static int wm1133_ev1_init(struct snd_soc_codec *codec)
214{
215 struct snd_soc_card *card = codec->socdev->card;
216
217 snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets,
218 ARRAY_SIZE(wm1133_ev1_widgets));
219
220 snd_soc_dapm_add_routes(codec, wm1133_ev1_map,
221 ARRAY_SIZE(wm1133_ev1_map));
222
223 /* Headphone jack detection */
224 snd_soc_jack_new(card, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
225 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
226 hp_jack_pins);
227 wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
228
229 /* Microphone jack detection */
230 snd_soc_jack_new(card, "Microphone",
231 SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack);
232 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
233 mic_jack_pins);
234 wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
235 SND_JACK_BTN_0);
236
237 snd_soc_dapm_force_enable_pin(codec, "Mic Bias");
238
239 return 0;
240}
241
242
243static struct snd_soc_dai_link wm1133_ev1_dai = {
244 .name = "WM1133-EV1",
245 .stream_name = "Audio",
246 .cpu_dai = &imx_ssi_pcm_dai[0],
247 .codec_dai = &wm8350_dai,
248 .init = wm1133_ev1_init,
249 .ops = &wm1133_ev1_ops,
250 .symmetric_rates = 1,
251};
252
253static struct snd_soc_card wm1133_ev1 = {
254 .name = "WM1133-EV1",
255 .platform = &imx_soc_platform,
256 .dai_link = &wm1133_ev1_dai,
257 .num_links = 1,
258};
259
260static struct snd_soc_device wm1133_ev1_snd_devdata = {
261 .card = &wm1133_ev1,
262 .codec_dev = &soc_codec_dev_wm8350,
263};
264
265static struct platform_device *wm1133_ev1_snd_device;
266
267static int __init wm1133_ev1_audio_init(void)
268{
269 int ret;
270 unsigned int ptcr, pdcr;
271
272 /* SSI0 mastered by port 5 */
273 ptcr = MXC_AUDMUX_V2_PTCR_SYN |
274 MXC_AUDMUX_V2_PTCR_TFSDIR |
275 MXC_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) |
276 MXC_AUDMUX_V2_PTCR_TCLKDIR |
277 MXC_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
278 pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5);
279 mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr);
280
281 ptcr = MXC_AUDMUX_V2_PTCR_SYN;
282 pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0);
283 mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr);
284
285 wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1);
286 if (!wm1133_ev1_snd_device)
287 return -ENOMEM;
288
289 platform_set_drvdata(wm1133_ev1_snd_device, &wm1133_ev1_snd_devdata);
290 wm1133_ev1_snd_devdata.dev = &wm1133_ev1_snd_device->dev;
291 ret = platform_device_add(wm1133_ev1_snd_device);
292
293 if (ret)
294 platform_device_put(wm1133_ev1_snd_device);
295
296 return ret;
297}
298module_init(wm1133_ev1_audio_init);
299
300static void __exit wm1133_ev1_audio_exit(void)
301{
302 platform_device_unregister(wm1133_ev1_snd_device);
303}
304module_exit(wm1133_ev1_audio_exit);
305
306MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
307MODULE_DESCRIPTION("Audio for WM1133-EV1 on i.MX31ADS");
308MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index f11963c21873..d542ea2ff6be 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -18,6 +18,16 @@ config SND_OMAP_SOC_N810
18 help 18 help
19 Say Y if you want to add support for SoC audio on Nokia N810. 19 Say Y if you want to add support for SoC audio on Nokia N810.
20 20
21config SND_OMAP_SOC_RX51
22 tristate "SoC Audio support for Nokia RX-51"
23 depends on SND_OMAP_SOC && MACH_NOKIA_RX51
24 select OMAP_MCBSP
25 select SND_OMAP_SOC_MCBSP
26 select SND_SOC_TLV320AIC3X
27 help
28 Say Y if you want to add support for SoC audio on Nokia RX-51
29 hardware. This is also known as Nokia N900 product.
30
21config SND_OMAP_SOC_AMS_DELTA 31config SND_OMAP_SOC_AMS_DELTA
22 tristate "SoC Audio support for Amstrad E3 (Delta) videophone" 32 tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
23 depends on SND_OMAP_SOC && MACH_AMS_DELTA 33 depends on SND_OMAP_SOC && MACH_AMS_DELTA
@@ -88,6 +98,15 @@ config SND_OMAP_SOC_SDP3430
88 Say Y if you want to add support for SoC audio on Texas Instruments 98 Say Y if you want to add support for SoC audio on Texas Instruments
89 SDP3430. 99 SDP3430.
90 100
101config SND_OMAP_SOC_SDP4430
102 tristate "SoC Audio support for Texas Instruments SDP4430"
103 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP
104 select SND_OMAP_SOC_MCPDM
105 select SND_SOC_TWL6040
106 help
107 Say Y if you want to add support for SoC audio on Texas Instruments
108 SDP4430.
109
91config SND_OMAP_SOC_OMAP3_PANDORA 110config SND_OMAP_SOC_OMAP3_PANDORA
92 tristate "SoC Audio support for OMAP3 Pandora" 111 tristate "SoC Audio support for OMAP3 Pandora"
93 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA 112 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 0bc00ca14b37..ba9fc650db28 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
9 9
10# OMAP Machine Support 10# OMAP Machine Support
11snd-soc-n810-objs := n810.o 11snd-soc-n810-objs := n810.o
12snd-soc-rx51-objs := rx51.o
12snd-soc-ams-delta-objs := ams-delta.o 13snd-soc-ams-delta-objs := ams-delta.o
13snd-soc-osk5912-objs := osk5912.o 14snd-soc-osk5912-objs := osk5912.o
14snd-soc-overo-objs := overo.o 15snd-soc-overo-objs := overo.o
@@ -16,12 +17,14 @@ snd-soc-omap2evm-objs := omap2evm.o
16snd-soc-omap3evm-objs := omap3evm.o 17snd-soc-omap3evm-objs := omap3evm.o
17snd-soc-am3517evm-objs := am3517evm.o 18snd-soc-am3517evm-objs := am3517evm.o
18snd-soc-sdp3430-objs := sdp3430.o 19snd-soc-sdp3430-objs := sdp3430.o
20snd-soc-sdp4430-objs := sdp4430.o
19snd-soc-omap3pandora-objs := omap3pandora.o 21snd-soc-omap3pandora-objs := omap3pandora.o
20snd-soc-omap3beagle-objs := omap3beagle.o 22snd-soc-omap3beagle-objs := omap3beagle.o
21snd-soc-zoom2-objs := zoom2.o 23snd-soc-zoom2-objs := zoom2.o
22snd-soc-igep0020-objs := igep0020.o 24snd-soc-igep0020-objs := igep0020.o
23 25
24obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 26obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
27obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
25obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o 28obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
26obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 29obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
27obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o 30obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
@@ -29,6 +32,7 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
29obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o 32obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
30obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o 33obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
31obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 34obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
35obj-$(CONFIG_SND_OMAP_SOC_SDP4430) += snd-soc-sdp4430.o
32obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 36obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
33obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o 37obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
34obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o 38obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
index 1dab4c14874d..90b8bf71c893 100644
--- a/sound/soc/omap/mcpdm.c
+++ b/sound/soc/omap/mcpdm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * mcpdm.c -- McPDM interface driver 2 * mcpdm.c -- McPDM interface driver
3 * 3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com> 4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 * Copyright (C) 2009 - Texas Instruments, Inc. 5 * Copyright (C) 2009 - Texas Instruments, Inc.
@@ -39,46 +39,46 @@ static struct omap_mcpdm *mcpdm;
39 39
40static inline void omap_mcpdm_write(u16 reg, u32 val) 40static inline void omap_mcpdm_write(u16 reg, u32 val)
41{ 41{
42 __raw_writel(val, mcpdm->io_base + reg); 42 __raw_writel(val, mcpdm->io_base + reg);
43} 43}
44 44
45static inline int omap_mcpdm_read(u16 reg) 45static inline int omap_mcpdm_read(u16 reg)
46{ 46{
47 return __raw_readl(mcpdm->io_base + reg); 47 return __raw_readl(mcpdm->io_base + reg);
48} 48}
49 49
50static void omap_mcpdm_reg_dump(void) 50static void omap_mcpdm_reg_dump(void)
51{ 51{
52 dev_dbg(mcpdm->dev, "***********************\n"); 52 dev_dbg(mcpdm->dev, "***********************\n");
53 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n", 53 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
54 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW)); 54 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW));
55 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n", 55 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
56 omap_mcpdm_read(MCPDM_IRQSTATUS)); 56 omap_mcpdm_read(MCPDM_IRQSTATUS));
57 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n", 57 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
58 omap_mcpdm_read(MCPDM_IRQENABLE_SET)); 58 omap_mcpdm_read(MCPDM_IRQENABLE_SET));
59 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n", 59 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
60 omap_mcpdm_read(MCPDM_IRQENABLE_CLR)); 60 omap_mcpdm_read(MCPDM_IRQENABLE_CLR));
61 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n", 61 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
62 omap_mcpdm_read(MCPDM_IRQWAKE_EN)); 62 omap_mcpdm_read(MCPDM_IRQWAKE_EN));
63 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n", 63 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
64 omap_mcpdm_read(MCPDM_DMAENABLE_SET)); 64 omap_mcpdm_read(MCPDM_DMAENABLE_SET));
65 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n", 65 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
66 omap_mcpdm_read(MCPDM_DMAENABLE_CLR)); 66 omap_mcpdm_read(MCPDM_DMAENABLE_CLR));
67 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n", 67 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
68 omap_mcpdm_read(MCPDM_DMAWAKEEN)); 68 omap_mcpdm_read(MCPDM_DMAWAKEEN));
69 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n", 69 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
70 omap_mcpdm_read(MCPDM_CTRL)); 70 omap_mcpdm_read(MCPDM_CTRL));
71 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n", 71 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
72 omap_mcpdm_read(MCPDM_DN_DATA)); 72 omap_mcpdm_read(MCPDM_DN_DATA));
73 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n", 73 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
74 omap_mcpdm_read(MCPDM_UP_DATA)); 74 omap_mcpdm_read(MCPDM_UP_DATA));
75 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n", 75 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
76 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN)); 76 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN));
77 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n", 77 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
78 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP)); 78 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP));
79 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n", 79 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n",
80 omap_mcpdm_read(MCPDM_DN_OFFSET)); 80 omap_mcpdm_read(MCPDM_DN_OFFSET));
81 dev_dbg(mcpdm->dev, "***********************\n"); 81 dev_dbg(mcpdm->dev, "***********************\n");
82} 82}
83 83
84/* 84/*
@@ -87,26 +87,26 @@ static void omap_mcpdm_reg_dump(void)
87 */ 87 */
88static void omap_mcpdm_reset_capture(int reset) 88static void omap_mcpdm_reset_capture(int reset)
89{ 89{
90 int ctrl = omap_mcpdm_read(MCPDM_CTRL); 90 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
91 91
92 if (reset) 92 if (reset)
93 ctrl |= SW_UP_RST; 93 ctrl |= SW_UP_RST;
94 else 94 else
95 ctrl &= ~SW_UP_RST; 95 ctrl &= ~SW_UP_RST;
96 96
97 omap_mcpdm_write(MCPDM_CTRL, ctrl); 97 omap_mcpdm_write(MCPDM_CTRL, ctrl);
98} 98}
99 99
100static void omap_mcpdm_reset_playback(int reset) 100static void omap_mcpdm_reset_playback(int reset)
101{ 101{
102 int ctrl = omap_mcpdm_read(MCPDM_CTRL); 102 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
103 103
104 if (reset) 104 if (reset)
105 ctrl |= SW_DN_RST; 105 ctrl |= SW_DN_RST;
106 else 106 else
107 ctrl &= ~SW_DN_RST; 107 ctrl &= ~SW_DN_RST;
108 108
109 omap_mcpdm_write(MCPDM_CTRL, ctrl); 109 omap_mcpdm_write(MCPDM_CTRL, ctrl);
110} 110}
111 111
112/* 112/*
@@ -115,14 +115,14 @@ static void omap_mcpdm_reset_playback(int reset)
115 */ 115 */
116void omap_mcpdm_start(int stream) 116void omap_mcpdm_start(int stream)
117{ 117{
118 int ctrl = omap_mcpdm_read(MCPDM_CTRL); 118 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
119 119
120 if (stream) 120 if (stream)
121 ctrl |= mcpdm->up_channels; 121 ctrl |= mcpdm->up_channels;
122 else 122 else
123 ctrl |= mcpdm->dn_channels; 123 ctrl |= mcpdm->dn_channels;
124 124
125 omap_mcpdm_write(MCPDM_CTRL, ctrl); 125 omap_mcpdm_write(MCPDM_CTRL, ctrl);
126} 126}
127 127
128/* 128/*
@@ -131,14 +131,14 @@ void omap_mcpdm_start(int stream)
131 */ 131 */
132void omap_mcpdm_stop(int stream) 132void omap_mcpdm_stop(int stream)
133{ 133{
134 int ctrl = omap_mcpdm_read(MCPDM_CTRL); 134 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
135 135
136 if (stream) 136 if (stream)
137 ctrl &= ~mcpdm->up_channels; 137 ctrl &= ~mcpdm->up_channels;
138 else 138 else
139 ctrl &= ~mcpdm->dn_channels; 139 ctrl &= ~mcpdm->dn_channels;
140 140
141 omap_mcpdm_write(MCPDM_CTRL, ctrl); 141 omap_mcpdm_write(MCPDM_CTRL, ctrl);
142} 142}
143 143
144/* 144/*
@@ -147,38 +147,38 @@ void omap_mcpdm_stop(int stream)
147 */ 147 */
148int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink) 148int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
149{ 149{
150 int irq_mask = 0; 150 int irq_mask = 0;
151 int ctrl; 151 int ctrl;
152 152
153 if (!uplink) 153 if (!uplink)
154 return -EINVAL; 154 return -EINVAL;
155 155
156 mcpdm->uplink = uplink; 156 mcpdm->uplink = uplink;
157 157
158 /* Enable irq request generation */ 158 /* Enable irq request generation */
159 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK; 159 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
160 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask); 160 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
161 161
162 /* Configure uplink threshold */ 162 /* Configure uplink threshold */
163 if (uplink->threshold > UP_THRES_MAX) 163 if (uplink->threshold > UP_THRES_MAX)
164 uplink->threshold = UP_THRES_MAX; 164 uplink->threshold = UP_THRES_MAX;
165 165
166 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold); 166 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold);
167 167
168 /* Configure DMA controller */ 168 /* Configure DMA controller */
169 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE); 169 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE);
170 170
171 /* Set pdm out format */ 171 /* Set pdm out format */
172 ctrl = omap_mcpdm_read(MCPDM_CTRL); 172 ctrl = omap_mcpdm_read(MCPDM_CTRL);
173 ctrl &= ~PDMOUTFORMAT; 173 ctrl &= ~PDMOUTFORMAT;
174 ctrl |= uplink->format & PDMOUTFORMAT; 174 ctrl |= uplink->format & PDMOUTFORMAT;
175 175
176 /* Uplink channels */ 176 /* Uplink channels */
177 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK); 177 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK);
178 178
179 omap_mcpdm_write(MCPDM_CTRL, ctrl); 179 omap_mcpdm_write(MCPDM_CTRL, ctrl);
180 180
181 return 0; 181 return 0;
182} 182}
183 183
184/* 184/*
@@ -187,38 +187,38 @@ int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
187 */ 187 */
188int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink) 188int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
189{ 189{
190 int irq_mask = 0; 190 int irq_mask = 0;
191 int ctrl; 191 int ctrl;
192 192
193 if (!downlink) 193 if (!downlink)
194 return -EINVAL; 194 return -EINVAL;
195 195
196 mcpdm->downlink = downlink; 196 mcpdm->downlink = downlink;
197 197
198 /* Enable irq request generation */ 198 /* Enable irq request generation */
199 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK; 199 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
200 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask); 200 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
201 201
202 /* Configure uplink threshold */ 202 /* Configure uplink threshold */
203 if (downlink->threshold > DN_THRES_MAX) 203 if (downlink->threshold > DN_THRES_MAX)
204 downlink->threshold = DN_THRES_MAX; 204 downlink->threshold = DN_THRES_MAX;
205 205
206 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold); 206 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold);
207 207
208 /* Enable DMA request generation */ 208 /* Enable DMA request generation */
209 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE); 209 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE);
210 210
211 /* Set pdm out format */ 211 /* Set pdm out format */
212 ctrl = omap_mcpdm_read(MCPDM_CTRL); 212 ctrl = omap_mcpdm_read(MCPDM_CTRL);
213 ctrl &= ~PDMOUTFORMAT; 213 ctrl &= ~PDMOUTFORMAT;
214 ctrl |= downlink->format & PDMOUTFORMAT; 214 ctrl |= downlink->format & PDMOUTFORMAT;
215 215
216 /* Downlink channels */ 216 /* Downlink channels */
217 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK); 217 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK);
218 218
219 omap_mcpdm_write(MCPDM_CTRL, ctrl); 219 omap_mcpdm_write(MCPDM_CTRL, ctrl);
220 220
221 return 0; 221 return 0;
222} 222}
223 223
224/* 224/*
@@ -227,24 +227,24 @@ int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
227 */ 227 */
228int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink) 228int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
229{ 229{
230 int irq_mask = 0; 230 int irq_mask = 0;
231 231
232 if (!uplink) 232 if (!uplink)
233 return -EINVAL; 233 return -EINVAL;
234 234
235 /* Disable irq request generation */ 235 /* Disable irq request generation */
236 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK; 236 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
237 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask); 237 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
238 238
239 /* Disable DMA request generation */ 239 /* Disable DMA request generation */
240 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE); 240 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE);
241 241
242 /* Clear Downlink channels */ 242 /* Clear Downlink channels */
243 mcpdm->up_channels = 0; 243 mcpdm->up_channels = 0;
244 244
245 mcpdm->uplink = NULL; 245 mcpdm->uplink = NULL;
246 246
247 return 0; 247 return 0;
248} 248}
249 249
250/* 250/*
@@ -253,124 +253,124 @@ int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
253 */ 253 */
254int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink) 254int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink)
255{ 255{
256 int irq_mask = 0; 256 int irq_mask = 0;
257 257
258 if (!downlink) 258 if (!downlink)
259 return -EINVAL; 259 return -EINVAL;
260 260
261 /* Disable irq request generation */ 261 /* Disable irq request generation */
262 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK; 262 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
263 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask); 263 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
264 264
265 /* Disable DMA request generation */ 265 /* Disable DMA request generation */
266 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE); 266 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE);
267 267
268 /* clear Downlink channels */ 268 /* clear Downlink channels */
269 mcpdm->dn_channels = 0; 269 mcpdm->dn_channels = 0;
270 270
271 mcpdm->downlink = NULL; 271 mcpdm->downlink = NULL;
272 272
273 return 0; 273 return 0;
274} 274}
275 275
276static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id) 276static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
277{ 277{
278 struct omap_mcpdm *mcpdm_irq = dev_id; 278 struct omap_mcpdm *mcpdm_irq = dev_id;
279 int irq_status; 279 int irq_status;
280 280
281 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS); 281 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS);
282 282
283 /* Acknowledge irq event */ 283 /* Acknowledge irq event */
284 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status); 284 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status);
285 285
286 if (irq & MCPDM_DN_IRQ_FULL) { 286 if (irq & MCPDM_DN_IRQ_FULL) {
287 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); 287 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
288 omap_mcpdm_reset_playback(1); 288 omap_mcpdm_reset_playback(1);
289 omap_mcpdm_playback_open(mcpdm_irq->downlink); 289 omap_mcpdm_playback_open(mcpdm_irq->downlink);
290 omap_mcpdm_reset_playback(0); 290 omap_mcpdm_reset_playback(0);
291 } 291 }
292 292
293 if (irq & MCPDM_DN_IRQ_EMPTY) { 293 if (irq & MCPDM_DN_IRQ_EMPTY) {
294 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); 294 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
295 omap_mcpdm_reset_playback(1); 295 omap_mcpdm_reset_playback(1);
296 omap_mcpdm_playback_open(mcpdm_irq->downlink); 296 omap_mcpdm_playback_open(mcpdm_irq->downlink);
297 omap_mcpdm_reset_playback(0); 297 omap_mcpdm_reset_playback(0);
298 } 298 }
299 299
300 if (irq & MCPDM_DN_IRQ) { 300 if (irq & MCPDM_DN_IRQ) {
301 dev_dbg(mcpdm_irq->dev, "DN write request\n"); 301 dev_dbg(mcpdm_irq->dev, "DN write request\n");
302 } 302 }
303 303
304 if (irq & MCPDM_UP_IRQ_FULL) { 304 if (irq & MCPDM_UP_IRQ_FULL) {
305 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); 305 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
306 omap_mcpdm_reset_capture(1); 306 omap_mcpdm_reset_capture(1);
307 omap_mcpdm_capture_open(mcpdm_irq->uplink); 307 omap_mcpdm_capture_open(mcpdm_irq->uplink);
308 omap_mcpdm_reset_capture(0); 308 omap_mcpdm_reset_capture(0);
309 } 309 }
310 310
311 if (irq & MCPDM_UP_IRQ_EMPTY) { 311 if (irq & MCPDM_UP_IRQ_EMPTY) {
312 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); 312 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
313 omap_mcpdm_reset_capture(1); 313 omap_mcpdm_reset_capture(1);
314 omap_mcpdm_capture_open(mcpdm_irq->uplink); 314 omap_mcpdm_capture_open(mcpdm_irq->uplink);
315 omap_mcpdm_reset_capture(0); 315 omap_mcpdm_reset_capture(0);
316 } 316 }
317 317
318 if (irq & MCPDM_UP_IRQ) { 318 if (irq & MCPDM_UP_IRQ) {
319 dev_dbg(mcpdm_irq->dev, "UP write request\n"); 319 dev_dbg(mcpdm_irq->dev, "UP write request\n");
320 } 320 }
321 321
322 return IRQ_HANDLED; 322 return IRQ_HANDLED;
323} 323}
324 324
325int omap_mcpdm_request(void) 325int omap_mcpdm_request(void)
326{ 326{
327 int ret; 327 int ret;
328 328
329 clk_enable(mcpdm->clk); 329 clk_enable(mcpdm->clk);
330 330
331 spin_lock(&mcpdm->lock); 331 spin_lock(&mcpdm->lock);
332 332
333 if (!mcpdm->free) { 333 if (!mcpdm->free) {
334 dev_err(mcpdm->dev, "McPDM interface is in use\n"); 334 dev_err(mcpdm->dev, "McPDM interface is in use\n");
335 spin_unlock(&mcpdm->lock); 335 spin_unlock(&mcpdm->lock);
336 ret = -EBUSY; 336 ret = -EBUSY;
337 goto err; 337 goto err;
338 } 338 }
339 mcpdm->free = 0; 339 mcpdm->free = 0;
340 340
341 spin_unlock(&mcpdm->lock); 341 spin_unlock(&mcpdm->lock);
342 342
343 /* Disable lines while request is ongoing */ 343 /* Disable lines while request is ongoing */
344 omap_mcpdm_write(MCPDM_CTRL, 0x00); 344 omap_mcpdm_write(MCPDM_CTRL, 0x00);
345 345
346 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 346 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
347 0, "McPDM", (void *)mcpdm); 347 0, "McPDM", (void *)mcpdm);
348 if (ret) { 348 if (ret) {
349 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n"); 349 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n");
350 goto err; 350 goto err;
351 } 351 }
352 352
353 return 0; 353 return 0;
354 354
355err: 355err:
356 clk_disable(mcpdm->clk); 356 clk_disable(mcpdm->clk);
357 return ret; 357 return ret;
358} 358}
359 359
360void omap_mcpdm_free(void) 360void omap_mcpdm_free(void)
361{ 361{
362 spin_lock(&mcpdm->lock); 362 spin_lock(&mcpdm->lock);
363 if (mcpdm->free) { 363 if (mcpdm->free) {
364 dev_err(mcpdm->dev, "McPDM interface is already free\n"); 364 dev_err(mcpdm->dev, "McPDM interface is already free\n");
365 spin_unlock(&mcpdm->lock); 365 spin_unlock(&mcpdm->lock);
366 return; 366 return;
367 } 367 }
368 mcpdm->free = 1; 368 mcpdm->free = 1;
369 spin_unlock(&mcpdm->lock); 369 spin_unlock(&mcpdm->lock);
370 370
371 clk_disable(mcpdm->clk); 371 clk_disable(mcpdm->clk);
372 372
373 free_irq(mcpdm->irq, (void *)mcpdm); 373 free_irq(mcpdm->irq, (void *)mcpdm);
374} 374}
375 375
376/* Enable/disable DC offset cancelation for the analog 376/* Enable/disable DC offset cancelation for the analog
@@ -378,108 +378,108 @@ void omap_mcpdm_free(void)
378 */ 378 */
379int omap_mcpdm_set_offset(int offset1, int offset2) 379int omap_mcpdm_set_offset(int offset1, int offset2)
380{ 380{
381 int offset; 381 int offset;
382 382
383 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX)) 383 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX))
384 return -EINVAL; 384 return -EINVAL;
385 385
386 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2); 386 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2);
387 387
388 /* offset cancellation for channel 1 */ 388 /* offset cancellation for channel 1 */
389 if (offset1) 389 if (offset1)
390 offset |= DN_OFST_RX1_EN; 390 offset |= DN_OFST_RX1_EN;
391 else 391 else
392 offset &= ~DN_OFST_RX1_EN; 392 offset &= ~DN_OFST_RX1_EN;
393 393
394 /* offset cancellation for channel 2 */ 394 /* offset cancellation for channel 2 */
395 if (offset2) 395 if (offset2)
396 offset |= DN_OFST_RX2_EN; 396 offset |= DN_OFST_RX2_EN;
397 else 397 else
398 offset &= ~DN_OFST_RX2_EN; 398 offset &= ~DN_OFST_RX2_EN;
399 399
400 omap_mcpdm_write(MCPDM_DN_OFFSET, offset); 400 omap_mcpdm_write(MCPDM_DN_OFFSET, offset);
401 401
402 return 0; 402 return 0;
403} 403}
404 404
405static int __devinit omap_mcpdm_probe(struct platform_device *pdev) 405static int __devinit omap_mcpdm_probe(struct platform_device *pdev)
406{ 406{
407 struct resource *res; 407 struct resource *res;
408 int ret = 0; 408 int ret = 0;
409 409
410 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); 410 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
411 if (!mcpdm) { 411 if (!mcpdm) {
412 ret = -ENOMEM; 412 ret = -ENOMEM;
413 goto exit; 413 goto exit;
414 } 414 }
415 415
416 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 416 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
417 if (res == NULL) { 417 if (res == NULL) {
418 dev_err(&pdev->dev, "no resource\n"); 418 dev_err(&pdev->dev, "no resource\n");
419 goto err_resource; 419 goto err_resource;
420 } 420 }
421 421
422 spin_lock_init(&mcpdm->lock); 422 spin_lock_init(&mcpdm->lock);
423 mcpdm->free = 1; 423 mcpdm->free = 1;
424 mcpdm->io_base = ioremap(res->start, resource_size(res)); 424 mcpdm->io_base = ioremap(res->start, resource_size(res));
425 if (!mcpdm->io_base) { 425 if (!mcpdm->io_base) {
426 ret = -ENOMEM; 426 ret = -ENOMEM;
427 goto err_resource; 427 goto err_resource;
428 } 428 }
429 429
430 mcpdm->irq = platform_get_irq(pdev, 0); 430 mcpdm->irq = platform_get_irq(pdev, 0);
431 431
432 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck"); 432 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck");
433 if (IS_ERR(mcpdm->clk)) { 433 if (IS_ERR(mcpdm->clk)) {
434 ret = PTR_ERR(mcpdm->clk); 434 ret = PTR_ERR(mcpdm->clk);
435 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret); 435 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret);
436 goto err_clk; 436 goto err_clk;
437 } 437 }
438 438
439 mcpdm->dev = &pdev->dev; 439 mcpdm->dev = &pdev->dev;
440 platform_set_drvdata(pdev, mcpdm); 440 platform_set_drvdata(pdev, mcpdm);
441 441
442 return 0; 442 return 0;
443 443
444err_clk: 444err_clk:
445 iounmap(mcpdm->io_base); 445 iounmap(mcpdm->io_base);
446err_resource: 446err_resource:
447 kfree(mcpdm); 447 kfree(mcpdm);
448exit: 448exit:
449 return ret; 449 return ret;
450} 450}
451 451
452static int __devexit omap_mcpdm_remove(struct platform_device *pdev) 452static int __devexit omap_mcpdm_remove(struct platform_device *pdev)
453{ 453{
454 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev); 454 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev);
455 455
456 platform_set_drvdata(pdev, NULL); 456 platform_set_drvdata(pdev, NULL);
457 457
458 clk_put(mcpdm_ptr->clk); 458 clk_put(mcpdm_ptr->clk);
459 459
460 iounmap(mcpdm_ptr->io_base); 460 iounmap(mcpdm_ptr->io_base);
461 461
462 mcpdm_ptr->clk = NULL; 462 mcpdm_ptr->clk = NULL;
463 mcpdm_ptr->free = 0; 463 mcpdm_ptr->free = 0;
464 mcpdm_ptr->dev = NULL; 464 mcpdm_ptr->dev = NULL;
465 465
466 kfree(mcpdm_ptr); 466 kfree(mcpdm_ptr);
467 467
468 return 0; 468 return 0;
469} 469}
470 470
471static struct platform_driver omap_mcpdm_driver = { 471static struct platform_driver omap_mcpdm_driver = {
472 .probe = omap_mcpdm_probe, 472 .probe = omap_mcpdm_probe,
473 .remove = __devexit_p(omap_mcpdm_remove), 473 .remove = __devexit_p(omap_mcpdm_remove),
474 .driver = { 474 .driver = {
475 .name = "omap-mcpdm", 475 .name = "omap-mcpdm",
476 }, 476 },
477}; 477};
478 478
479static struct platform_device *omap_mcpdm_device; 479static struct platform_device *omap_mcpdm_device;
480 480
481static int __init omap_mcpdm_init(void) 481static int __init omap_mcpdm_init(void)
482{ 482{
483 return platform_driver_register(&omap_mcpdm_driver); 483 return platform_driver_register(&omap_mcpdm_driver);
484} 484}
485arch_initcall(omap_mcpdm_init); 485arch_initcall(omap_mcpdm_init);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 8ad9dc901007..6f44cb4d30b8 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -256,6 +256,31 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
256 return err; 256 return err;
257} 257}
258 258
259static snd_pcm_sframes_t omap_mcbsp_dai_delay(
260 struct snd_pcm_substream *substream,
261 struct snd_soc_dai *dai)
262{
263 struct snd_soc_pcm_runtime *rtd = substream->private_data;
264 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
265 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
266 u16 fifo_use;
267 snd_pcm_sframes_t delay;
268
269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
270 fifo_use = omap_mcbsp_get_tx_delay(mcbsp_data->bus_id);
271 else
272 fifo_use = omap_mcbsp_get_rx_delay(mcbsp_data->bus_id);
273
274 /*
275 * Divide the used locations with the channel count to get the
276 * FIFO usage in samples (don't care about partial samples in the
277 * buffer).
278 */
279 delay = fifo_use / substream->runtime->channels;
280
281 return delay;
282}
283
259static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, 284static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
260 struct snd_pcm_hw_params *params, 285 struct snd_pcm_hw_params *params,
261 struct snd_soc_dai *dai) 286 struct snd_soc_dai *dai)
@@ -295,8 +320,18 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
295 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 320 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
296 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 321 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
297 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; 322 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
298 omap_mcbsp_dai_dma_params[id][substream->stream].data_type = 323 switch (params_format(params)) {
299 OMAP_DMA_DATA_TYPE_S16; 324 case SNDRV_PCM_FORMAT_S16_LE:
325 omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
326 OMAP_DMA_DATA_TYPE_S16;
327 break;
328 case SNDRV_PCM_FORMAT_S32_LE:
329 omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
330 OMAP_DMA_DATA_TYPE_S32;
331 break;
332 default:
333 return -EINVAL;
334 }
300 335
301 snd_soc_dai_set_dma_data(cpu_dai, substream, 336 snd_soc_dai_set_dma_data(cpu_dai, substream,
302 &omap_mcbsp_dai_dma_params[id][substream->stream]); 337 &omap_mcbsp_dai_dma_params[id][substream->stream]);
@@ -308,7 +343,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
308 343
309 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; 344 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
310 wpf = channels = params_channels(params); 345 wpf = channels = params_channels(params);
311 if (channels == 2 && format == SND_SOC_DAIFMT_I2S) { 346 if (channels == 2 && (format == SND_SOC_DAIFMT_I2S ||
347 format == SND_SOC_DAIFMT_LEFT_J)) {
312 /* Use dual-phase frames */ 348 /* Use dual-phase frames */
313 regs->rcr2 |= RPHASE; 349 regs->rcr2 |= RPHASE;
314 regs->xcr2 |= XPHASE; 350 regs->xcr2 |= XPHASE;
@@ -330,6 +366,14 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
330 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16); 366 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16);
331 regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16); 367 regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16);
332 break; 368 break;
369 case SNDRV_PCM_FORMAT_S32_LE:
370 /* Set word lengths */
371 wlen = 32;
372 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_32);
373 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_32);
374 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_32);
375 regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_32);
376 break;
333 default: 377 default:
334 /* Unsupported PCM format */ 378 /* Unsupported PCM format */
335 return -EINVAL; 379 return -EINVAL;
@@ -353,6 +397,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
353 /* Set FS period and length in terms of bit clock periods */ 397 /* Set FS period and length in terms of bit clock periods */
354 switch (format) { 398 switch (format) {
355 case SND_SOC_DAIFMT_I2S: 399 case SND_SOC_DAIFMT_I2S:
400 case SND_SOC_DAIFMT_LEFT_J:
356 regs->srgr2 |= FPER(framesize - 1); 401 regs->srgr2 |= FPER(framesize - 1);
357 regs->srgr1 |= FWID((framesize >> 1) - 1); 402 regs->srgr1 |= FWID((framesize >> 1) - 1);
358 break; 403 break;
@@ -404,6 +449,14 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
404 regs->rcr2 |= RDATDLY(1); 449 regs->rcr2 |= RDATDLY(1);
405 regs->xcr2 |= XDATDLY(1); 450 regs->xcr2 |= XDATDLY(1);
406 break; 451 break;
452 case SND_SOC_DAIFMT_LEFT_J:
453 /* 0-bit data delay */
454 regs->rcr2 |= RDATDLY(0);
455 regs->xcr2 |= XDATDLY(0);
456 regs->spcr1 |= RJUST(2);
457 /* Invert FS polarity configuration */
458 temp_fmt ^= SND_SOC_DAIFMT_NB_IF;
459 break;
407 case SND_SOC_DAIFMT_DSP_A: 460 case SND_SOC_DAIFMT_DSP_A:
408 /* 1-bit data delay */ 461 /* 1-bit data delay */
409 regs->rcr2 |= RDATDLY(1); 462 regs->rcr2 |= RDATDLY(1);
@@ -609,6 +662,7 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
609 .startup = omap_mcbsp_dai_startup, 662 .startup = omap_mcbsp_dai_startup,
610 .shutdown = omap_mcbsp_dai_shutdown, 663 .shutdown = omap_mcbsp_dai_shutdown,
611 .trigger = omap_mcbsp_dai_trigger, 664 .trigger = omap_mcbsp_dai_trigger,
665 .delay = omap_mcbsp_dai_delay,
612 .hw_params = omap_mcbsp_dai_hw_params, 666 .hw_params = omap_mcbsp_dai_hw_params,
613 .set_fmt = omap_mcbsp_dai_set_dai_fmt, 667 .set_fmt = omap_mcbsp_dai_set_dai_fmt,
614 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, 668 .set_clkdiv = omap_mcbsp_dai_set_clkdiv,
@@ -623,13 +677,15 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
623 .channels_min = 1, \ 677 .channels_min = 1, \
624 .channels_max = 16, \ 678 .channels_max = 16, \
625 .rates = OMAP_MCBSP_RATES, \ 679 .rates = OMAP_MCBSP_RATES, \
626 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 680 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
681 SNDRV_PCM_FMTBIT_S32_LE, \
627 }, \ 682 }, \
628 .capture = { \ 683 .capture = { \
629 .channels_min = 1, \ 684 .channels_min = 1, \
630 .channels_max = 16, \ 685 .channels_max = 16, \
631 .rates = OMAP_MCBSP_RATES, \ 686 .rates = OMAP_MCBSP_RATES, \
632 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 687 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
688 SNDRV_PCM_FMTBIT_S32_LE, \
633 }, \ 689 }, \
634 .ops = &omap_mcbsp_dai_ops, \ 690 .ops = &omap_mcbsp_dai_ops, \
635 .private_data = &mcbsp_data[(link_id)].bus_id, \ 691 .private_data = &mcbsp_data[(link_id)].bus_id, \
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index de10f76baded..87ce842fa2e8 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -188,8 +188,6 @@ static int omap3pandora_out_init(struct snd_soc_codec *codec)
188 int ret; 188 int ret;
189 189
190 /* All TWL4030 output pins are floating */ 190 /* All TWL4030 output pins are floating */
191 snd_soc_dapm_nc_pin(codec, "OUTL");
192 snd_soc_dapm_nc_pin(codec, "OUTR");
193 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 191 snd_soc_dapm_nc_pin(codec, "EARPIECE");
194 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 192 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
195 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 193 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
new file mode 100644
index 000000000000..47d831ef2dbb
--- /dev/null
+++ b/sound/soc/omap/rx51.c
@@ -0,0 +1,294 @@
1/*
2 * rx51.c -- SoC audio for Nokia RX-51
3 *
4 * Copyright (C) 2008 - 2009 Nokia Corporation
5 *
6 * Contact: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 * Eduardo Valentin <eduardo.valentin@nokia.com>
8 * Jarkko Nikula <jhnikula@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#include <linux/delay.h>
27#include <linux/gpio.h>
28#include <linux/platform_device.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33
34#include <asm/mach-types.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/tlv320aic3x.h"
39
40/*
41 * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
42 * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
43 */
44#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7)
45
46static int rx51_spk_func;
47static int rx51_dmic_func;
48
49static void rx51_ext_control(struct snd_soc_codec *codec)
50{
51 if (rx51_spk_func)
52 snd_soc_dapm_enable_pin(codec, "Ext Spk");
53 else
54 snd_soc_dapm_disable_pin(codec, "Ext Spk");
55 if (rx51_dmic_func)
56 snd_soc_dapm_enable_pin(codec, "DMic");
57 else
58 snd_soc_dapm_disable_pin(codec, "DMic");
59
60 snd_soc_dapm_sync(codec);
61}
62
63static int rx51_startup(struct snd_pcm_substream *substream)
64{
65 struct snd_pcm_runtime *runtime = substream->runtime;
66 struct snd_soc_pcm_runtime *rtd = substream->private_data;
67 struct snd_soc_codec *codec = rtd->socdev->card->codec;
68
69 snd_pcm_hw_constraint_minmax(runtime,
70 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
71 rx51_ext_control(codec);
72
73 return 0;
74}
75
76static int rx51_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params)
78{
79 struct snd_soc_pcm_runtime *rtd = substream->private_data;
80 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
81 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
82 int err;
83
84 /* Set codec DAI configuration */
85 err = snd_soc_dai_set_fmt(codec_dai,
86 SND_SOC_DAIFMT_DSP_A |
87 SND_SOC_DAIFMT_IB_NF |
88 SND_SOC_DAIFMT_CBM_CFM);
89 if (err < 0)
90 return err;
91
92 /* Set cpu DAI configuration */
93 err = snd_soc_dai_set_fmt(cpu_dai,
94 SND_SOC_DAIFMT_DSP_A |
95 SND_SOC_DAIFMT_IB_NF |
96 SND_SOC_DAIFMT_CBM_CFM);
97 if (err < 0)
98 return err;
99
100 /* Set the codec system clock for DAC and ADC */
101 return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000,
102 SND_SOC_CLOCK_IN);
103}
104
105static struct snd_soc_ops rx51_ops = {
106 .startup = rx51_startup,
107 .hw_params = rx51_hw_params,
108};
109
110static int rx51_get_spk(struct snd_kcontrol *kcontrol,
111 struct snd_ctl_elem_value *ucontrol)
112{
113 ucontrol->value.integer.value[0] = rx51_spk_func;
114
115 return 0;
116}
117
118static int rx51_set_spk(struct snd_kcontrol *kcontrol,
119 struct snd_ctl_elem_value *ucontrol)
120{
121 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
122
123 if (rx51_spk_func == ucontrol->value.integer.value[0])
124 return 0;
125
126 rx51_spk_func = ucontrol->value.integer.value[0];
127 rx51_ext_control(codec);
128
129 return 1;
130}
131
132static int rx51_spk_event(struct snd_soc_dapm_widget *w,
133 struct snd_kcontrol *k, int event)
134{
135 if (SND_SOC_DAPM_EVENT_ON(event))
136 gpio_set_value(RX51_SPEAKER_AMP_TWL_GPIO, 1);
137 else
138 gpio_set_value(RX51_SPEAKER_AMP_TWL_GPIO, 0);
139
140 return 0;
141}
142
143static int rx51_get_input(struct snd_kcontrol *kcontrol,
144 struct snd_ctl_elem_value *ucontrol)
145{
146 ucontrol->value.integer.value[0] = rx51_dmic_func;
147
148 return 0;
149}
150
151static int rx51_set_input(struct snd_kcontrol *kcontrol,
152 struct snd_ctl_elem_value *ucontrol)
153{
154 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
155
156 if (rx51_dmic_func == ucontrol->value.integer.value[0])
157 return 0;
158
159 rx51_dmic_func = ucontrol->value.integer.value[0];
160 rx51_ext_control(codec);
161
162 return 1;
163}
164
165static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
166 SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
167 SND_SOC_DAPM_MIC("DMic", NULL),
168};
169
170static const struct snd_soc_dapm_route audio_map[] = {
171 {"Ext Spk", NULL, "HPLOUT"},
172 {"Ext Spk", NULL, "HPROUT"},
173
174 {"DMic Rate 64", NULL, "Mic Bias 2V"},
175 {"Mic Bias 2V", NULL, "DMic"},
176};
177
178static const char *spk_function[] = {"Off", "On"};
179static const char *input_function[] = {"ADC", "Digital Mic"};
180
181static const struct soc_enum rx51_enum[] = {
182 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function),
183 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function),
184};
185
186static const struct snd_kcontrol_new aic34_rx51_controls[] = {
187 SOC_ENUM_EXT("Speaker Function", rx51_enum[0],
188 rx51_get_spk, rx51_set_spk),
189 SOC_ENUM_EXT("Input Select", rx51_enum[1],
190 rx51_get_input, rx51_set_input),
191};
192
193static int rx51_aic34_init(struct snd_soc_codec *codec)
194{
195 int err;
196
197 /* Set up NC codec pins */
198 snd_soc_dapm_nc_pin(codec, "MIC3L");
199 snd_soc_dapm_nc_pin(codec, "MIC3R");
200 snd_soc_dapm_nc_pin(codec, "LINE1R");
201
202 /* Add RX-51 specific controls */
203 err = snd_soc_add_controls(codec, aic34_rx51_controls,
204 ARRAY_SIZE(aic34_rx51_controls));
205 if (err < 0)
206 return err;
207
208 /* Add RX-51 specific widgets */
209 snd_soc_dapm_new_controls(codec, aic34_dapm_widgets,
210 ARRAY_SIZE(aic34_dapm_widgets));
211
212 /* Set up RX-51 specific audio path audio_map */
213 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
214
215 snd_soc_dapm_sync(codec);
216
217 return 0;
218}
219
220/* Digital audio interface glue - connects codec <--> CPU */
221static struct snd_soc_dai_link rx51_dai[] = {
222 {
223 .name = "TLV320AIC34",
224 .stream_name = "AIC34",
225 .cpu_dai = &omap_mcbsp_dai[0],
226 .codec_dai = &aic3x_dai,
227 .init = rx51_aic34_init,
228 .ops = &rx51_ops,
229 },
230};
231
232/* Audio private data */
233static struct aic3x_setup_data rx51_aic34_setup = {
234 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
235 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
236};
237
238/* Audio card */
239static struct snd_soc_card rx51_sound_card = {
240 .name = "RX-51",
241 .dai_link = rx51_dai,
242 .num_links = ARRAY_SIZE(rx51_dai),
243 .platform = &omap_soc_platform,
244};
245
246/* Audio subsystem */
247static struct snd_soc_device rx51_snd_devdata = {
248 .card = &rx51_sound_card,
249 .codec_dev = &soc_codec_dev_aic3x,
250 .codec_data = &rx51_aic34_setup,
251};
252
253static struct platform_device *rx51_snd_device;
254
255static int __init rx51_soc_init(void)
256{
257 int err;
258
259 if (!machine_is_nokia_rx51())
260 return -ENODEV;
261
262 rx51_snd_device = platform_device_alloc("soc-audio", -1);
263 if (!rx51_snd_device) {
264 err = -ENOMEM;
265 goto err1;
266 }
267
268 platform_set_drvdata(rx51_snd_device, &rx51_snd_devdata);
269 rx51_snd_devdata.dev = &rx51_snd_device->dev;
270 *(unsigned int *)rx51_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
271
272 err = platform_device_add(rx51_snd_device);
273 if (err)
274 goto err2;
275
276 return 0;
277err2:
278 platform_device_put(rx51_snd_device);
279err1:
280
281 return err;
282}
283
284static void __exit rx51_soc_exit(void)
285{
286 platform_device_unregister(rx51_snd_device);
287}
288
289module_init(rx51_soc_init);
290module_exit(rx51_soc_exit);
291
292MODULE_AUTHOR("Nokia Corporation");
293MODULE_DESCRIPTION("ALSA SoC Nokia RX-51");
294MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
new file mode 100644
index 000000000000..4ebbde6b565f
--- /dev/null
+++ b/sound/soc/omap/sdp4430.c
@@ -0,0 +1,233 @@
1/*
2 * sdp4430.c -- SoC audio for TI OMAP4430 SDP
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29#include <asm/mach-types.h>
30#include <plat/hardware.h>
31#include <plat/mux.h>
32
33#include "mcpdm.h"
34#include "omap-mcpdm.h"
35#include "omap-pcm.h"
36#include "../codecs/twl6040.h"
37
38static int twl6040_power_mode;
39
40static int sdp4430_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params)
42{
43 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
45 int clk_id, freq;
46 int ret;
47
48 if (twl6040_power_mode) {
49 clk_id = TWL6040_SYSCLK_SEL_HPPLL;
50 freq = 38400000;
51 } else {
52 clk_id = TWL6040_SYSCLK_SEL_LPPLL;
53 freq = 32768;
54 }
55
56 /* set the codec mclk */
57 ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
58 SND_SOC_CLOCK_IN);
59 if (ret) {
60 printk(KERN_ERR "can't set codec system clock\n");
61 return ret;
62 }
63}
64
65static struct snd_soc_ops sdp4430_ops = {
66 .hw_params = sdp4430_hw_params,
67};
68
69static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol,
70 struct snd_ctl_elem_value *ucontrol)
71{
72 ucontrol->value.integer.value[0] = twl6040_power_mode;
73 return 0;
74}
75
76static int sdp4430_set_power_mode(struct snd_kcontrol *kcontrol,
77 struct snd_ctl_elem_value *ucontrol)
78{
79 if (twl6040_power_mode == ucontrol->value.integer.value[0])
80 return 0;
81
82 twl6040_power_mode = ucontrol->value.integer.value[0];
83
84 return 1;
85}
86
87static const char *power_texts[] = {"Low-Power", "High-Performance"};
88
89static const struct soc_enum sdp4430_enum[] = {
90 SOC_ENUM_SINGLE_EXT(2, power_texts),
91};
92
93static const struct snd_kcontrol_new sdp4430_controls[] = {
94 SOC_ENUM_EXT("TWL6040 Power Mode", sdp4430_enum[0],
95 sdp4430_get_power_mode, sdp4430_set_power_mode),
96};
97
98/* SDP4430 machine DAPM */
99static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
100 SND_SOC_DAPM_MIC("Ext Mic", NULL),
101 SND_SOC_DAPM_SPK("Ext Spk", NULL),
102 SND_SOC_DAPM_MIC("Headset Mic", NULL),
103 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
104 SND_SOC_DAPM_SPK("Earphone Spk", NULL),
105};
106
107static const struct snd_soc_dapm_route audio_map[] = {
108 /* External Mics: MAINMIC, SUBMIC with bias*/
109 {"MAINMIC", NULL, "Main Mic Bias"},
110 {"SUBMIC", NULL, "Main Mic Bias"},
111 {"Main Mic Bias", NULL, "Ext Mic"},
112
113 /* External Speakers: HFL, HFR */
114 {"Ext Spk", NULL, "HFL"},
115 {"Ext Spk", NULL, "HFR"},
116
117 /* Headset Mic: HSMIC with bias */
118 {"HSMIC", NULL, "Headset Mic Bias"},
119 {"Headset Mic Bias", NULL, "Headset Mic"},
120
121 /* Headset Stereophone (Headphone): HSOL, HSOR */
122 {"Headset Stereophone", NULL, "HSOL"},
123 {"Headset Stereophone", NULL, "HSOR"},
124
125 /* Earphone speaker */
126 {"Earphone Spk", NULL, "EP"},
127};
128
129static int sdp4430_twl6040_init(struct snd_soc_codec *codec)
130{
131 int ret;
132
133 /* Add SDP4430 specific controls */
134 ret = snd_soc_add_controls(codec, sdp4430_controls,
135 ARRAY_SIZE(sdp4430_controls));
136 if (ret)
137 return ret;
138
139 /* Add SDP4430 specific widgets */
140 ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6040_dapm_widgets,
141 ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
142 if (ret)
143 return ret;
144
145 /* Set up SDP4430 specific audio path audio_map */
146 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
147
148 /* SDP4430 connected pins */
149 snd_soc_dapm_enable_pin(codec, "Ext Mic");
150 snd_soc_dapm_enable_pin(codec, "Ext Spk");
151 snd_soc_dapm_enable_pin(codec, "Headset Mic");
152 snd_soc_dapm_enable_pin(codec, "Headset Stereophone");
153
154 /* TWL6040 not connected pins */
155 snd_soc_dapm_nc_pin(codec, "AFML");
156 snd_soc_dapm_nc_pin(codec, "AFMR");
157
158 ret = snd_soc_dapm_sync(codec);
159
160 return ret;
161}
162
163/* Digital audio interface glue - connects codec <--> CPU */
164static struct snd_soc_dai_link sdp4430_dai = {
165 .name = "TWL6040",
166 .stream_name = "TWL6040",
167 .cpu_dai = &omap_mcpdm_dai,
168 .codec_dai = &twl6040_dai,
169 .init = sdp4430_twl6040_init,
170 .ops = &sdp4430_ops,
171};
172
173/* Audio machine driver */
174static struct snd_soc_card snd_soc_sdp4430 = {
175 .name = "SDP4430",
176 .platform = &omap_soc_platform,
177 .dai_link = &sdp4430_dai,
178 .num_links = 1,
179};
180
181/* Audio subsystem */
182static struct snd_soc_device sdp4430_snd_devdata = {
183 .card = &snd_soc_sdp4430,
184 .codec_dev = &soc_codec_dev_twl6040,
185};
186
187static struct platform_device *sdp4430_snd_device;
188
189static int __init sdp4430_soc_init(void)
190{
191 int ret;
192
193 if (!machine_is_omap_4430sdp()) {
194 pr_debug("Not SDP4430!\n");
195 return -ENODEV;
196 }
197 printk(KERN_INFO "SDP4430 SoC init\n");
198
199 sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
200 if (!sdp4430_snd_device) {
201 printk(KERN_ERR "Platform device allocation failed\n");
202 return -ENOMEM;
203 }
204
205 platform_set_drvdata(sdp4430_snd_device, &sdp4430_snd_devdata);
206 sdp4430_snd_devdata.dev = &sdp4430_snd_device->dev;
207
208 ret = platform_device_add(sdp4430_snd_device);
209 if (ret)
210 goto err;
211
212 /* Codec starts in HP mode */
213 twl6040_power_mode = 1;
214
215 return 0;
216
217err:
218 printk(KERN_ERR "Unable to add platform device\n");
219 platform_device_put(sdp4430_snd_device);
220 return ret;
221}
222module_init(sdp4430_soc_init);
223
224static void __exit sdp4430_soc_exit(void)
225{
226 platform_device_unregister(sdp4430_snd_device);
227}
228module_exit(sdp4430_soc_exit);
229
230MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
231MODULE_DESCRIPTION("ALSA SoC SDP4430");
232MODULE_LICENSE("GPL");
233
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index f90a2ac888cf..50a94ee76ecc 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -181,9 +181,6 @@ static int zoom2_twl4030_init(struct snd_soc_codec *codec)
181 snd_soc_dapm_nc_pin(codec, "CARKITMIC"); 181 snd_soc_dapm_nc_pin(codec, "CARKITMIC");
182 snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); 182 snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
183 snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); 183 snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
184
185 snd_soc_dapm_nc_pin(codec, "OUTL");
186 snd_soc_dapm_nc_pin(codec, "OUTR");
187 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 184 snd_soc_dapm_nc_pin(codec, "EARPIECE");
188 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 185 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
189 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 186 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 376e14a9c273..e30c8325f35e 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -23,6 +23,7 @@ config SND_PXA2XX_SOC_I2S
23 23
24config SND_PXA_SOC_SSP 24config SND_PXA_SOC_SSP
25 tristate 25 tristate
26 select PXA_SSP
26 27
27config SND_PXA2XX_SOC_CORGI 28config SND_PXA2XX_SOC_CORGI
28 tristate "SoC Audio support for Sharp Zaurus SL-C7x0" 29 tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
@@ -42,6 +43,14 @@ config SND_PXA2XX_SOC_SPITZ
42 Say Y if you want to add support for SoC audio on Sharp 43 Say Y if you want to add support for SoC audio on Sharp
43 Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita). 44 Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita).
44 45
46config SND_PXA2XX_SOC_Z2
47 tristate "SoC Audio support for Zipit Z2"
48 depends on SND_PXA2XX_SOC && MACH_ZIPIT2
49 select SND_PXA2XX_SOC_I2S
50 select SND_SOC_WM8750
51 help
52 Say Y if you want to add support for SoC audio on Zipit Z2.
53
45config SND_PXA2XX_SOC_POODLE 54config SND_PXA2XX_SOC_POODLE
46 tristate "SoC Audio support for Poodle" 55 tristate "SoC Audio support for Poodle"
47 depends on SND_PXA2XX_SOC && MACH_POODLE 56 depends on SND_PXA2XX_SOC && MACH_POODLE
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index f3e08fd40ca2..caa03d8f4789 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -22,6 +22,7 @@ snd-soc-palm27x-objs := palm27x.o
22snd-soc-zylonite-objs := zylonite.o 22snd-soc-zylonite-objs := zylonite.o
23snd-soc-magician-objs := magician.o 23snd-soc-magician-objs := magician.o
24snd-soc-mioa701-objs := mioa701_wm9713.o 24snd-soc-mioa701-objs := mioa701_wm9713.o
25snd-soc-z2-objs := z2.o
25snd-soc-imote2-objs := imote2.o 26snd-soc-imote2-objs := imote2.o
26snd-soc-raumfeld-objs := raumfeld.o 27snd-soc-raumfeld-objs := raumfeld.o
27 28
@@ -36,6 +37,7 @@ obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
36obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o 37obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
37obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o 38obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
38obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 39obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
40obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
39obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 41obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
40obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 42obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
41obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o 43obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 544fd9566f4d..a1fd23e0e3d0 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -32,9 +32,8 @@
32 32
33#include <mach/hardware.h> 33#include <mach/hardware.h>
34#include <mach/dma.h> 34#include <mach/dma.h>
35#include <mach/regs-ssp.h>
36#include <mach/audio.h> 35#include <mach/audio.h>
37#include <mach/ssp.h> 36#include <plat/ssp.h>
38 37
39#include "pxa2xx-pcm.h" 38#include "pxa2xx-pcm.h"
40#include "pxa-ssp.h" 39#include "pxa-ssp.h"
@@ -57,15 +56,15 @@ struct ssp_priv {
57static void dump_registers(struct ssp_device *ssp) 56static void dump_registers(struct ssp_device *ssp)
58{ 57{
59 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n", 58 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
60 ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1), 59 pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
61 ssp_read_reg(ssp, SSTO)); 60 pxa_ssp_read_reg(ssp, SSTO));
62 61
63 dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n", 62 dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
64 ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR), 63 pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
65 ssp_read_reg(ssp, SSACD)); 64 pxa_ssp_read_reg(ssp, SSACD));
66} 65}
67 66
68static void ssp_enable(struct ssp_device *ssp) 67static void pxa_ssp_enable(struct ssp_device *ssp)
69{ 68{
70 uint32_t sscr0; 69 uint32_t sscr0;
71 70
@@ -73,7 +72,7 @@ static void ssp_enable(struct ssp_device *ssp)
73 __raw_writel(sscr0, ssp->mmio_base + SSCR0); 72 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
74} 73}
75 74
76static void ssp_disable(struct ssp_device *ssp) 75static void pxa_ssp_disable(struct ssp_device *ssp)
77{ 76{
78 uint32_t sscr0; 77 uint32_t sscr0;
79 78
@@ -87,7 +86,7 @@ struct pxa2xx_pcm_dma_data {
87}; 86};
88 87
89static struct pxa2xx_pcm_dma_params * 88static struct pxa2xx_pcm_dma_params *
90ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) 89pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
91{ 90{
92 struct pxa2xx_pcm_dma_data *dma; 91 struct pxa2xx_pcm_dma_data *dma;
93 92
@@ -119,7 +118,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
119 118
120 if (!cpu_dai->active) { 119 if (!cpu_dai->active) {
121 clk_enable(ssp->clk); 120 clk_enable(ssp->clk);
122 ssp_disable(ssp); 121 pxa_ssp_disable(ssp);
123 } 122 }
124 123
125 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); 124 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
@@ -137,7 +136,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
137 struct ssp_device *ssp = priv->ssp; 136 struct ssp_device *ssp = priv->ssp;
138 137
139 if (!cpu_dai->active) { 138 if (!cpu_dai->active) {
140 ssp_disable(ssp); 139 pxa_ssp_disable(ssp);
141 clk_disable(ssp->clk); 140 clk_disable(ssp->clk);
142 } 141 }
143 142
@@ -160,7 +159,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
160 priv->to = __raw_readl(ssp->mmio_base + SSTO); 159 priv->to = __raw_readl(ssp->mmio_base + SSTO);
161 priv->psp = __raw_readl(ssp->mmio_base + SSPSP); 160 priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
162 161
163 ssp_disable(ssp); 162 pxa_ssp_disable(ssp);
164 clk_disable(ssp->clk); 163 clk_disable(ssp->clk);
165 return 0; 164 return 0;
166} 165}
@@ -180,7 +179,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
180 __raw_writel(priv->psp, ssp->mmio_base + SSPSP); 179 __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
181 180
182 if (cpu_dai->active) 181 if (cpu_dai->active)
183 ssp_enable(ssp); 182 pxa_ssp_enable(ssp);
184 else 183 else
185 clk_disable(ssp->clk); 184 clk_disable(ssp->clk);
186 185
@@ -196,9 +195,9 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
196 * ssp_set_clkdiv - set SSP clock divider 195 * ssp_set_clkdiv - set SSP clock divider
197 * @div: serial clock rate divider 196 * @div: serial clock rate divider
198 */ 197 */
199static void ssp_set_scr(struct ssp_device *ssp, u32 div) 198static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
200{ 199{
201 u32 sscr0 = ssp_read_reg(ssp, SSCR0); 200 u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
202 201
203 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) { 202 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
204 sscr0 &= ~0x0000ff00; 203 sscr0 &= ~0x0000ff00;
@@ -207,15 +206,15 @@ static void ssp_set_scr(struct ssp_device *ssp, u32 div)
207 sscr0 &= ~0x000fff00; 206 sscr0 &= ~0x000fff00;
208 sscr0 |= (div - 1) << 8; /* 1..4096 */ 207 sscr0 |= (div - 1) << 8; /* 1..4096 */
209 } 208 }
210 ssp_write_reg(ssp, SSCR0, sscr0); 209 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
211} 210}
212 211
213/** 212/**
214 * ssp_get_clkdiv - get SSP clock divider 213 * pxa_ssp_get_clkdiv - get SSP clock divider
215 */ 214 */
216static u32 ssp_get_scr(struct ssp_device *ssp) 215static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
217{ 216{
218 u32 sscr0 = ssp_read_reg(ssp, SSCR0); 217 u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
219 u32 div; 218 u32 div;
220 219
221 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) 220 if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
@@ -235,7 +234,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
235 struct ssp_device *ssp = priv->ssp; 234 struct ssp_device *ssp = priv->ssp;
236 int val; 235 int val;
237 236
238 u32 sscr0 = ssp_read_reg(ssp, SSCR0) & 237 u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
239 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); 238 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
240 239
241 dev_dbg(&ssp->pdev->dev, 240 dev_dbg(&ssp->pdev->dev,
@@ -263,7 +262,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
263 break; 262 break;
264 case PXA_SSP_CLK_AUDIO: 263 case PXA_SSP_CLK_AUDIO:
265 priv->sysclk = 0; 264 priv->sysclk = 0;
266 ssp_set_scr(ssp, 1); 265 pxa_ssp_set_scr(ssp, 1);
267 sscr0 |= SSCR0_ACS; 266 sscr0 |= SSCR0_ACS;
268 break; 267 break;
269 default: 268 default:
@@ -274,8 +273,8 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
274 * on PXA2xx. On PXA3xx it must be enabled when doing so. */ 273 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
275 if (!cpu_is_pxa3xx()) 274 if (!cpu_is_pxa3xx())
276 clk_disable(ssp->clk); 275 clk_disable(ssp->clk);
277 val = ssp_read_reg(ssp, SSCR0) | sscr0; 276 val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
278 ssp_write_reg(ssp, SSCR0, val); 277 pxa_ssp_write_reg(ssp, SSCR0, val);
279 if (!cpu_is_pxa3xx()) 278 if (!cpu_is_pxa3xx())
280 clk_enable(ssp->clk); 279 clk_enable(ssp->clk);
281 280
@@ -294,11 +293,11 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
294 293
295 switch (div_id) { 294 switch (div_id) {
296 case PXA_SSP_AUDIO_DIV_ACDS: 295 case PXA_SSP_AUDIO_DIV_ACDS:
297 val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div); 296 val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
298 ssp_write_reg(ssp, SSACD, val); 297 pxa_ssp_write_reg(ssp, SSACD, val);
299 break; 298 break;
300 case PXA_SSP_AUDIO_DIV_SCDB: 299 case PXA_SSP_AUDIO_DIV_SCDB:
301 val = ssp_read_reg(ssp, SSACD); 300 val = pxa_ssp_read_reg(ssp, SSACD);
302 val &= ~SSACD_SCDB; 301 val &= ~SSACD_SCDB;
303#if defined(CONFIG_PXA3xx) 302#if defined(CONFIG_PXA3xx)
304 if (cpu_is_pxa3xx()) 303 if (cpu_is_pxa3xx())
@@ -321,10 +320,10 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
321 default: 320 default:
322 return -EINVAL; 321 return -EINVAL;
323 } 322 }
324 ssp_write_reg(ssp, SSACD, val); 323 pxa_ssp_write_reg(ssp, SSACD, val);
325 break; 324 break;
326 case PXA_SSP_DIV_SCR: 325 case PXA_SSP_DIV_SCR:
327 ssp_set_scr(ssp, div); 326 pxa_ssp_set_scr(ssp, div);
328 break; 327 break;
329 default: 328 default:
330 return -ENODEV; 329 return -ENODEV;
@@ -341,11 +340,11 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
341{ 340{
342 struct ssp_priv *priv = cpu_dai->private_data; 341 struct ssp_priv *priv = cpu_dai->private_data;
343 struct ssp_device *ssp = priv->ssp; 342 struct ssp_device *ssp = priv->ssp;
344 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; 343 u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
345 344
346#if defined(CONFIG_PXA3xx) 345#if defined(CONFIG_PXA3xx)
347 if (cpu_is_pxa3xx()) 346 if (cpu_is_pxa3xx())
348 ssp_write_reg(ssp, SSACDD, 0); 347 pxa_ssp_write_reg(ssp, SSACDD, 0);
349#endif 348#endif
350 349
351 switch (freq_out) { 350 switch (freq_out) {
@@ -383,7 +382,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
383 val = tmp; 382 val = tmp;
384 383
385 val = (val << 16) | 64; 384 val = (val << 16) | 64;
386 ssp_write_reg(ssp, SSACDD, val); 385 pxa_ssp_write_reg(ssp, SSACDD, val);
387 386
388 ssacd |= (0x6 << 4); 387 ssacd |= (0x6 << 4);
389 388
@@ -397,7 +396,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
397 return -EINVAL; 396 return -EINVAL;
398 } 397 }
399 398
400 ssp_write_reg(ssp, SSACD, ssacd); 399 pxa_ssp_write_reg(ssp, SSACD, ssacd);
401 400
402 return 0; 401 return 0;
403} 402}
@@ -412,7 +411,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
412 struct ssp_device *ssp = priv->ssp; 411 struct ssp_device *ssp = priv->ssp;
413 u32 sscr0; 412 u32 sscr0;
414 413
415 sscr0 = ssp_read_reg(ssp, SSCR0); 414 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
416 sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS); 415 sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
417 416
418 /* set slot width */ 417 /* set slot width */
@@ -429,10 +428,10 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
429 sscr0 |= SSCR0_SlotsPerFrm(slots); 428 sscr0 |= SSCR0_SlotsPerFrm(slots);
430 429
431 /* set active slot mask */ 430 /* set active slot mask */
432 ssp_write_reg(ssp, SSTSA, tx_mask); 431 pxa_ssp_write_reg(ssp, SSTSA, tx_mask);
433 ssp_write_reg(ssp, SSRSA, rx_mask); 432 pxa_ssp_write_reg(ssp, SSRSA, rx_mask);
434 } 433 }
435 ssp_write_reg(ssp, SSCR0, sscr0); 434 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
436 435
437 return 0; 436 return 0;
438} 437}
@@ -447,12 +446,12 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
447 struct ssp_device *ssp = priv->ssp; 446 struct ssp_device *ssp = priv->ssp;
448 u32 sscr1; 447 u32 sscr1;
449 448
450 sscr1 = ssp_read_reg(ssp, SSCR1); 449 sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
451 if (tristate) 450 if (tristate)
452 sscr1 &= ~SSCR1_TTE; 451 sscr1 &= ~SSCR1_TTE;
453 else 452 else
454 sscr1 |= SSCR1_TTE; 453 sscr1 |= SSCR1_TTE;
455 ssp_write_reg(ssp, SSCR1, sscr1); 454 pxa_ssp_write_reg(ssp, SSCR1, sscr1);
456 455
457 return 0; 456 return 0;
458} 457}
@@ -476,14 +475,14 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
476 return 0; 475 return 0;
477 476
478 /* we can only change the settings if the port is not in use */ 477 /* we can only change the settings if the port is not in use */
479 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) { 478 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
480 dev_err(&ssp->pdev->dev, 479 dev_err(&ssp->pdev->dev,
481 "can't change hardware dai format: stream is in use"); 480 "can't change hardware dai format: stream is in use");
482 return -EINVAL; 481 return -EINVAL;
483 } 482 }
484 483
485 /* reset port settings */ 484 /* reset port settings */
486 sscr0 = ssp_read_reg(ssp, SSCR0) & 485 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
487 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); 486 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
488 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7); 487 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
489 sspsp = 0; 488 sspsp = 0;
@@ -535,9 +534,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
535 return -EINVAL; 534 return -EINVAL;
536 } 535 }
537 536
538 ssp_write_reg(ssp, SSCR0, sscr0); 537 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
539 ssp_write_reg(ssp, SSCR1, sscr1); 538 pxa_ssp_write_reg(ssp, SSCR1, sscr1);
540 ssp_write_reg(ssp, SSPSP, sspsp); 539 pxa_ssp_write_reg(ssp, SSPSP, sspsp);
541 540
542 dump_registers(ssp); 541 dump_registers(ssp);
543 542
@@ -566,7 +565,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
566 u32 sscr0; 565 u32 sscr0;
567 u32 sspsp; 566 u32 sspsp;
568 int width = snd_pcm_format_physical_width(params_format(params)); 567 int width = snd_pcm_format_physical_width(params_format(params));
569 int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; 568 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
570 struct pxa2xx_pcm_dma_params *dma_data; 569 struct pxa2xx_pcm_dma_params *dma_data;
571 570
572 dma_data = snd_soc_dai_get_dma_data(dai, substream); 571 dma_data = snd_soc_dai_get_dma_data(dai, substream);
@@ -578,22 +577,22 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
578 * to force 16-bit frame width on the wire (for S16_LE), even 577 * to force 16-bit frame width on the wire (for S16_LE), even
579 * with two channels. Use 16-bit DMA transfers for this case. 578 * with two channels. Use 16-bit DMA transfers for this case.
580 */ 579 */
581 dma_data = ssp_get_dma_params(ssp, 580 dma_data = pxa_ssp_get_dma_params(ssp,
582 ((chn == 2) && (ttsa != 1)) || (width == 32), 581 ((chn == 2) && (ttsa != 1)) || (width == 32),
583 substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 582 substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
584 583
585 snd_soc_dai_set_dma_data(dai, substream, dma_data); 584 snd_soc_dai_set_dma_data(dai, substream, dma_data);
586 585
587 /* we can only change the settings if the port is not in use */ 586 /* we can only change the settings if the port is not in use */
588 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 587 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
589 return 0; 588 return 0;
590 589
591 /* clear selected SSP bits */ 590 /* clear selected SSP bits */
592 sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS); 591 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
593 ssp_write_reg(ssp, SSCR0, sscr0); 592 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
594 593
595 /* bit size */ 594 /* bit size */
596 sscr0 = ssp_read_reg(ssp, SSCR0); 595 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
597 switch (params_format(params)) { 596 switch (params_format(params)) {
598 case SNDRV_PCM_FORMAT_S16_LE: 597 case SNDRV_PCM_FORMAT_S16_LE:
599#ifdef CONFIG_PXA3xx 598#ifdef CONFIG_PXA3xx
@@ -609,13 +608,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
609 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16)); 608 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
610 break; 609 break;
611 } 610 }
612 ssp_write_reg(ssp, SSCR0, sscr0); 611 pxa_ssp_write_reg(ssp, SSCR0, sscr0);
613 612
614 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 613 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
615 case SND_SOC_DAIFMT_I2S: 614 case SND_SOC_DAIFMT_I2S:
616 sspsp = ssp_read_reg(ssp, SSPSP); 615 sspsp = pxa_ssp_read_reg(ssp, SSPSP);
617 616
618 if ((ssp_get_scr(ssp) == 4) && (width == 16)) { 617 if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) {
619 /* This is a special case where the bitclk is 64fs 618 /* This is a special case where the bitclk is 64fs
620 * and we're not dealing with 2*32 bits of audio 619 * and we're not dealing with 2*32 bits of audio
621 * samples. 620 * samples.
@@ -649,7 +648,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
649 sspsp |= SSPSP_DMYSTRT(1); 648 sspsp |= SSPSP_DMYSTRT(1);
650 } 649 }
651 650
652 ssp_write_reg(ssp, SSPSP, sspsp); 651 pxa_ssp_write_reg(ssp, SSPSP, sspsp);
653 break; 652 break;
654 default: 653 default:
655 break; 654 break;
@@ -680,45 +679,45 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
680 679
681 switch (cmd) { 680 switch (cmd) {
682 case SNDRV_PCM_TRIGGER_RESUME: 681 case SNDRV_PCM_TRIGGER_RESUME:
683 ssp_enable(ssp); 682 pxa_ssp_enable(ssp);
684 break; 683 break;
685 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 684 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
686 val = ssp_read_reg(ssp, SSCR1); 685 val = pxa_ssp_read_reg(ssp, SSCR1);
687 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 686 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
688 val |= SSCR1_TSRE; 687 val |= SSCR1_TSRE;
689 else 688 else
690 val |= SSCR1_RSRE; 689 val |= SSCR1_RSRE;
691 ssp_write_reg(ssp, SSCR1, val); 690 pxa_ssp_write_reg(ssp, SSCR1, val);
692 val = ssp_read_reg(ssp, SSSR); 691 val = pxa_ssp_read_reg(ssp, SSSR);
693 ssp_write_reg(ssp, SSSR, val); 692 pxa_ssp_write_reg(ssp, SSSR, val);
694 break; 693 break;
695 case SNDRV_PCM_TRIGGER_START: 694 case SNDRV_PCM_TRIGGER_START:
696 val = ssp_read_reg(ssp, SSCR1); 695 val = pxa_ssp_read_reg(ssp, SSCR1);
697 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 696 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
698 val |= SSCR1_TSRE; 697 val |= SSCR1_TSRE;
699 else 698 else
700 val |= SSCR1_RSRE; 699 val |= SSCR1_RSRE;
701 ssp_write_reg(ssp, SSCR1, val); 700 pxa_ssp_write_reg(ssp, SSCR1, val);
702 ssp_enable(ssp); 701 pxa_ssp_enable(ssp);
703 break; 702 break;
704 case SNDRV_PCM_TRIGGER_STOP: 703 case SNDRV_PCM_TRIGGER_STOP:
705 val = ssp_read_reg(ssp, SSCR1); 704 val = pxa_ssp_read_reg(ssp, SSCR1);
706 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 705 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
707 val &= ~SSCR1_TSRE; 706 val &= ~SSCR1_TSRE;
708 else 707 else
709 val &= ~SSCR1_RSRE; 708 val &= ~SSCR1_RSRE;
710 ssp_write_reg(ssp, SSCR1, val); 709 pxa_ssp_write_reg(ssp, SSCR1, val);
711 break; 710 break;
712 case SNDRV_PCM_TRIGGER_SUSPEND: 711 case SNDRV_PCM_TRIGGER_SUSPEND:
713 ssp_disable(ssp); 712 pxa_ssp_disable(ssp);
714 break; 713 break;
715 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 714 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
716 val = ssp_read_reg(ssp, SSCR1); 715 val = pxa_ssp_read_reg(ssp, SSCR1);
717 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 716 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
718 val &= ~SSCR1_TSRE; 717 val &= ~SSCR1_TSRE;
719 else 718 else
720 val &= ~SSCR1_RSRE; 719 val &= ~SSCR1_RSRE;
721 ssp_write_reg(ssp, SSCR1, val); 720 pxa_ssp_write_reg(ssp, SSCR1, val);
722 break; 721 break;
723 722
724 default: 723 default:
@@ -740,7 +739,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
740 if (!priv) 739 if (!priv)
741 return -ENOMEM; 740 return -ENOMEM;
742 741
743 priv->ssp = ssp_request(dai->id + 1, "SoC audio"); 742 priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
744 if (priv->ssp == NULL) { 743 if (priv->ssp == NULL) {
745 ret = -ENODEV; 744 ret = -ENODEV;
746 goto err_priv; 745 goto err_priv;
@@ -760,7 +759,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
760 struct snd_soc_dai *dai) 759 struct snd_soc_dai *dai)
761{ 760{
762 struct ssp_priv *priv = dai->private_data; 761 struct ssp_priv *priv = dai->private_data;
763 ssp_free(priv->ssp); 762 pxa_ssp_free(priv->ssp);
764} 763}
765 764
766#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 765#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index c4cd2acaacb4..1941a357e8c4 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -322,19 +322,44 @@ static struct snd_soc_card snd_soc_spitz = {
322 .num_links = 1, 322 .num_links = 1,
323}; 323};
324 324
325/* spitz audio private data */
326static struct wm8750_setup_data spitz_wm8750_setup = {
327 .i2c_bus = 0,
328 .i2c_address = 0x1b,
329};
330
331/* spitz audio subsystem */ 325/* spitz audio subsystem */
332static struct snd_soc_device spitz_snd_devdata = { 326static struct snd_soc_device spitz_snd_devdata = {
333 .card = &snd_soc_spitz, 327 .card = &snd_soc_spitz,
334 .codec_dev = &soc_codec_dev_wm8750, 328 .codec_dev = &soc_codec_dev_wm8750,
335 .codec_data = &spitz_wm8750_setup,
336}; 329};
337 330
331/*
332 * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
333 * New drivers should register the wm8750 I2C device in the machine
334 * setup code (under arch/arm for ARM systems).
335 */
336static int wm8750_i2c_register(void)
337{
338 struct i2c_board_info info;
339 struct i2c_adapter *adapter;
340 struct i2c_client *client;
341
342 memset(&info, 0, sizeof(struct i2c_board_info));
343 info.addr = 0x1b;
344 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
345
346 adapter = i2c_get_adapter(0);
347 if (!adapter) {
348 printk(KERN_ERR "can't get i2c adapter 0\n");
349 return -ENODEV;
350 }
351
352 client = i2c_new_device(adapter, &info);
353 i2c_put_adapter(adapter);
354 if (!client) {
355 printk(KERN_ERR "can't add i2c device at 0x%x\n",
356 (unsigned int)info.addr);
357 return -ENODEV;
358 }
359
360 return 0;
361}
362
338static struct platform_device *spitz_snd_device; 363static struct platform_device *spitz_snd_device;
339 364
340static int __init spitz_init(void) 365static int __init spitz_init(void)
@@ -344,6 +369,10 @@ static int __init spitz_init(void)
344 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 369 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
345 return -ENODEV; 370 return -ENODEV;
346 371
372 ret = wm8750_i2c_setup();
373 if (ret != 0)
374 return ret;
375
347 spitz_snd_device = platform_device_alloc("soc-audio", -1); 376 spitz_snd_device = platform_device_alloc("soc-audio", -1);
348 if (!spitz_snd_device) 377 if (!spitz_snd_device)
349 return -ENOMEM; 378 return -ENOMEM;
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
new file mode 100644
index 000000000000..4e4d2fa8ddc5
--- /dev/null
+++ b/sound/soc/pxa/z2.c
@@ -0,0 +1,246 @@
1/*
2 * linux/sound/soc/pxa/z2.c
3 *
4 * SoC Audio driver for Aeronix Zipit Z2
5 *
6 * Copyright (C) 2009 Ken McGuire <kenm@desertweyr.com>
7 * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/timer.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/gpio.h>
20
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/jack.h>
26
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include <mach/audio.h>
30#include <mach/z2.h>
31
32#include "../codecs/wm8750.h"
33#include "pxa2xx-pcm.h"
34#include "pxa2xx-i2s.h"
35
36static struct snd_soc_card snd_soc_z2;
37
38static int z2_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 unsigned int clk = 0;
45 int ret = 0;
46
47 switch (params_rate(params)) {
48 case 8000:
49 case 16000:
50 case 48000:
51 case 96000:
52 clk = 12288000;
53 break;
54 case 11025:
55 case 22050:
56 case 44100:
57 clk = 11289600;
58 break;
59 }
60
61 /* set codec DAI configuration */
62 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
63 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
64 if (ret < 0)
65 return ret;
66
67 /* set cpu DAI configuration */
68 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
69 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
70 if (ret < 0)
71 return ret;
72
73 /* set the codec system clock for DAC and ADC */
74 ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
75 SND_SOC_CLOCK_IN);
76 if (ret < 0)
77 return ret;
78
79 /* set the I2S system clock as input (unused) */
80 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
81 SND_SOC_CLOCK_IN);
82 if (ret < 0)
83 return ret;
84
85 return 0;
86}
87
88static struct snd_soc_jack hs_jack;
89
90/* Headset jack detection DAPM pins */
91static struct snd_soc_jack_pin hs_jack_pins[] = {
92 {
93 .pin = "Mic Jack",
94 .mask = SND_JACK_MICROPHONE,
95 },
96 {
97 .pin = "Headphone Jack",
98 .mask = SND_JACK_HEADPHONE,
99 },
100};
101
102/* Headset jack detection gpios */
103static struct snd_soc_jack_gpio hs_jack_gpios[] = {
104 {
105 .gpio = GPIO37_ZIPITZ2_HEADSET_DETECT,
106 .name = "hsdet-gpio",
107 .report = SND_JACK_HEADSET,
108 .debounce_time = 200,
109 },
110};
111
112/* z2 machine dapm widgets */
113static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
114 SND_SOC_DAPM_HP("Headphone Jack", NULL),
115 SND_SOC_DAPM_MIC("Mic Jack", NULL),
116 SND_SOC_DAPM_SPK("Ext Spk", NULL),
117
118 /* headset is a mic and mono headphone */
119 SND_SOC_DAPM_HP("Headset Jack", NULL),
120};
121
122/* Z2 machine audio_map */
123static const struct snd_soc_dapm_route audio_map[] = {
124
125 /* headphone connected to LOUT1, ROUT1 */
126 {"Headphone Jack", NULL, "LOUT1"},
127 {"Headphone Jack", NULL, "ROUT1"},
128
129 /* ext speaker connected to LOUT2, ROUT2 */
130 {"Ext Spk", NULL , "ROUT2"},
131 {"Ext Spk", NULL , "LOUT2"},
132
133 /* mic is connected to R input 2 - with bias */
134 {"RINPUT2", NULL, "Mic Bias"},
135 {"Mic Bias", NULL, "Mic Jack"},
136};
137
138/*
139 * Logic for a wm8750 as connected on a Z2 Device
140 */
141static int z2_wm8750_init(struct snd_soc_codec *codec)
142{
143 int ret;
144
145 /* NC codec pins */
146 snd_soc_dapm_disable_pin(codec, "LINPUT3");
147 snd_soc_dapm_disable_pin(codec, "RINPUT3");
148 snd_soc_dapm_disable_pin(codec, "OUT3");
149 snd_soc_dapm_disable_pin(codec, "MONO");
150
151 /* Add z2 specific widgets */
152 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets,
153 ARRAY_SIZE(wm8750_dapm_widgets));
154
155 /* Set up z2 specific audio paths */
156 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
157
158 ret = snd_soc_dapm_sync(codec);
159 if (ret)
160 goto err;
161
162 /* Jack detection API stuff */
163 ret = snd_soc_jack_new(&snd_soc_z2, "Headset Jack", SND_JACK_HEADSET,
164 &hs_jack);
165 if (ret)
166 goto err;
167
168 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
169 hs_jack_pins);
170 if (ret)
171 goto err;
172
173 ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
174 hs_jack_gpios);
175 if (ret)
176 goto err;
177
178 return 0;
179
180err:
181 return ret;
182}
183
184static struct snd_soc_ops z2_ops = {
185 .hw_params = z2_hw_params,
186};
187
188/* z2 digital audio interface glue - connects codec <--> CPU */
189static struct snd_soc_dai_link z2_dai = {
190 .name = "wm8750",
191 .stream_name = "WM8750",
192 .cpu_dai = &pxa_i2s_dai,
193 .codec_dai = &wm8750_dai,
194 .init = z2_wm8750_init,
195 .ops = &z2_ops,
196};
197
198/* z2 audio machine driver */
199static struct snd_soc_card snd_soc_z2 = {
200 .name = "Z2",
201 .platform = &pxa2xx_soc_platform,
202 .dai_link = &z2_dai,
203 .num_links = 1,
204};
205
206/* z2 audio subsystem */
207static struct snd_soc_device z2_snd_devdata = {
208 .card = &snd_soc_z2,
209 .codec_dev = &soc_codec_dev_wm8750,
210};
211
212static struct platform_device *z2_snd_device;
213
214static int __init z2_init(void)
215{
216 int ret;
217
218 if (!machine_is_zipit2())
219 return -ENODEV;
220
221 z2_snd_device = platform_device_alloc("soc-audio", -1);
222 if (!z2_snd_device)
223 return -ENOMEM;
224
225 platform_set_drvdata(z2_snd_device, &z2_snd_devdata);
226 z2_snd_devdata.dev = &z2_snd_device->dev;
227 ret = platform_device_add(z2_snd_device);
228
229 if (ret)
230 platform_device_put(z2_snd_device);
231
232 return ret;
233}
234
235static void __exit z2_exit(void)
236{
237 platform_device_unregister(z2_snd_device);
238}
239
240module_init(z2_init);
241module_exit(z2_exit);
242
243MODULE_AUTHOR("Ken McGuire <kenm@desertweyr.com>, "
244 "Marek Vasut <marek.vasut@gmail.com>");
245MODULE_DESCRIPTION("ALSA SoC ZipitZ2");
246MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 15fe57e5a232..2a7cc222d098 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -24,6 +24,11 @@ config SND_S3C64XX_SOC_I2S
24 select SND_S3C_I2SV2_SOC 24 select SND_S3C_I2SV2_SOC
25 select S3C64XX_DMA 25 select S3C64XX_DMA
26 26
27config SND_S3C64XX_SOC_I2S_V4
28 tristate
29 select SND_S3C_I2SV2_SOC
30 select S3C64XX_DMA
31
27config SND_S3C_SOC_PCM 32config SND_S3C_SOC_PCM
28 tristate 33 tristate
29 34
@@ -59,12 +64,11 @@ config SND_S3C24XX_SOC_JIVE_WM8750
59 64
60config SND_S3C64XX_SOC_WM8580 65config SND_S3C64XX_SOC_WM8580
61 tristate "SoC I2S Audio support for WM8580 on SMDK64XX" 66 tristate "SoC I2S Audio support for WM8580 on SMDK64XX"
62 depends on SND_S3C24XX_SOC && (MACH_SMDK6400 || MACH_SMDK6410) 67 depends on SND_S3C24XX_SOC && MACH_SMDK6410
63 depends on BROKEN
64 select SND_SOC_WM8580 68 select SND_SOC_WM8580
65 select SND_S3C64XX_SOC_I2S 69 select SND_S3C64XX_SOC_I2S_V4
66 help 70 help
67 Sat Y if you want to add support for SoC audio on the SMDK64XX. 71 Say Y if you want to add support for SoC audio on the SMDK6410.
68 72
69config SND_S3C24XX_SOC_SMDK2443_WM9710 73config SND_S3C24XX_SOC_SMDK2443_WM9710
70 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 74 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index df071a376fa2..81d8dc503f87 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -4,6 +4,7 @@ snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o 4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o 5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
6snd-soc-s3c-ac97-objs := s3c-ac97.o 6snd-soc-s3c-ac97-objs := s3c-ac97.o
7snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o
7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o 8snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
8snd-soc-s3c-pcm-objs := s3c-pcm.o 9snd-soc-s3c-pcm-objs := s3c-pcm.o
9 10
@@ -12,6 +13,7 @@ obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
12obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o 13obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o
13obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o 14obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
14obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o 15obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
16obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o
15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o 17obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
16obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o 18obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o
17 19
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c
index 59dc2c6b56d9..8c108b121c10 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/s3c24xx/jive_wm8750.c
@@ -70,7 +70,7 @@ static int jive_hw_params(struct snd_pcm_substream *substream,
70 } 70 }
71 71
72 s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), 72 s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
73 s3c2412_get_iisclk()); 73 s3c_i2sv2_get_clock(cpu_dai));
74 74
75 /* set codec DAI configuration */ 75 /* set codec DAI configuration */
76 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 76 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
@@ -152,15 +152,10 @@ static struct snd_soc_card snd_soc_machine_jive = {
152 .num_links = 1, 152 .num_links = 1,
153}; 153};
154 154
155/* jive audio private data */
156static struct wm8750_setup_data jive_wm8750_setup = {
157};
158
159/* jive audio subsystem */ 155/* jive audio subsystem */
160static struct snd_soc_device jive_snd_devdata = { 156static struct snd_soc_device jive_snd_devdata = {
161 .card = &snd_soc_machine_jive, 157 .card = &snd_soc_machine_jive,
162 .codec_dev = &soc_codec_dev_wm8750, 158 .codec_dev = &soc_codec_dev_wm8750,
163 .codec_data = &jive_wm8750_setup,
164}; 159};
165 160
166static struct platform_device *jive_snd_device; 161static struct platform_device *jive_snd_device;
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
index dea83d30a5c9..209c25994c7e 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
@@ -362,6 +362,14 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
362 snd_soc_dapm_disable_pin(codec, "Handset Mic"); 362 snd_soc_dapm_disable_pin(codec, "Handset Mic");
363 snd_soc_dapm_disable_pin(codec, "Handset Spk"); 363 snd_soc_dapm_disable_pin(codec, "Handset Spk");
364 364
365 /* allow audio paths from the GSM modem to run during suspend */
366 snd_soc_dapm_ignore_suspend(codec, "Stereo Out");
367 snd_soc_dapm_ignore_suspend(codec, "GSM Line Out");
368 snd_soc_dapm_ignore_suspend(codec, "GSM Line In");
369 snd_soc_dapm_ignore_suspend(codec, "Headset Mic");
370 snd_soc_dapm_ignore_suspend(codec, "Handset Mic");
371 snd_soc_dapm_ignore_suspend(codec, "Handset Spk");
372
365 snd_soc_dapm_sync(codec); 373 snd_soc_dapm_sync(codec);
366 374
367 return 0; 375 return 0;
diff --git a/sound/soc/s3c24xx/regs-i2s-v2.h b/sound/soc/s3c24xx/regs-i2s-v2.h
new file mode 100644
index 000000000000..5e5e5680580b
--- /dev/null
+++ b/sound/soc/s3c24xx/regs-i2s-v2.h
@@ -0,0 +1,115 @@
1/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h
2 *
3 * Copyright 2007 Simtec Electronics <linux@simtec.co.uk>
4 * http://armlinux.simtec.co.uk/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * S3C2412 IIS register definition
11*/
12
13#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H
14#define __ASM_ARCH_REGS_S3C2412_IIS_H
15
16#define S3C2412_IISCON (0x00)
17#define S3C2412_IISMOD (0x04)
18#define S3C2412_IISFIC (0x08)
19#define S3C2412_IISPSR (0x0C)
20#define S3C2412_IISTXD (0x10)
21#define S3C2412_IISRXD (0x14)
22
23#define S5PC1XX_IISFICS 0x18
24#define S5PC1XX_IISTXDS 0x1C
25
26#define S5PC1XX_IISCON_SW_RST (1 << 31)
27#define S5PC1XX_IISCON_FRXOFSTATUS (1 << 26)
28#define S5PC1XX_IISCON_FRXORINTEN (1 << 25)
29#define S5PC1XX_IISCON_FTXSURSTAT (1 << 24)
30#define S5PC1XX_IISCON_FTXSURINTEN (1 << 23)
31#define S5PC1XX_IISCON_TXSDMAPAUSE (1 << 20)
32#define S5PC1XX_IISCON_TXSDMACTIVE (1 << 18)
33
34#define S3C64XX_IISCON_FTXURSTATUS (1 << 17)
35#define S3C64XX_IISCON_FTXURINTEN (1 << 16)
36#define S3C64XX_IISCON_TXFIFO2_EMPTY (1 << 15)
37#define S3C64XX_IISCON_TXFIFO1_EMPTY (1 << 14)
38#define S3C64XX_IISCON_TXFIFO2_FULL (1 << 13)
39#define S3C64XX_IISCON_TXFIFO1_FULL (1 << 12)
40
41#define S3C2412_IISCON_LRINDEX (1 << 11)
42#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10)
43#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9)
44#define S3C2412_IISCON_TXFIFO_FULL (1 << 8)
45#define S3C2412_IISCON_RXFIFO_FULL (1 << 7)
46#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6)
47#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5)
48#define S3C2412_IISCON_TXCH_PAUSE (1 << 4)
49#define S3C2412_IISCON_RXCH_PAUSE (1 << 3)
50#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2)
51#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1)
52#define S3C2412_IISCON_IIS_ACTIVE (1 << 0)
53
54#define S5PC1XX_IISMOD_OPCLK_CDCLK_OUT (0 << 30)
55#define S5PC1XX_IISMOD_OPCLK_CDCLK_IN (1 << 30)
56#define S5PC1XX_IISMOD_OPCLK_BCLK_OUT (2 << 30)
57#define S5PC1XX_IISMOD_OPCLK_PCLK (3 << 30)
58#define S5PC1XX_IISMOD_OPCLK_MASK (3 << 30)
59#define S5PC1XX_IISMOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
60#define S5PC1XX_IISMOD_BLCS_MASK 0x3
61#define S5PC1XX_IISMOD_BLCS_SHIFT 26
62#define S5PC1XX_IISMOD_BLCP_MASK 0x3
63#define S5PC1XX_IISMOD_BLCP_SHIFT 24
64
65#define S3C64XX_IISMOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
66#define S3C64XX_IISMOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
67#define S3C64XX_IISMOD_C1DD_HHALF (1 << 19)
68#define S3C64XX_IISMOD_C1DD_LHALF (1 << 18)
69#define S3C64XX_IISMOD_DC2_EN (1 << 17)
70#define S3C64XX_IISMOD_DC1_EN (1 << 16)
71#define S3C64XX_IISMOD_BLC_16BIT (0 << 13)
72#define S3C64XX_IISMOD_BLC_8BIT (1 << 13)
73#define S3C64XX_IISMOD_BLC_24BIT (2 << 13)
74#define S3C64XX_IISMOD_BLC_MASK (3 << 13)
75
76#define S3C2412_IISMOD_IMS_SYSMUX (1 << 10)
77#define S3C2412_IISMOD_SLAVE (1 << 11)
78#define S3C2412_IISMOD_MODE_TXONLY (0 << 8)
79#define S3C2412_IISMOD_MODE_RXONLY (1 << 8)
80#define S3C2412_IISMOD_MODE_TXRX (2 << 8)
81#define S3C2412_IISMOD_MODE_MASK (3 << 8)
82#define S3C2412_IISMOD_LR_LLOW (0 << 7)
83#define S3C2412_IISMOD_LR_RLOW (1 << 7)
84#define S3C2412_IISMOD_SDF_IIS (0 << 5)
85#define S3C2412_IISMOD_SDF_MSB (1 << 5)
86#define S3C2412_IISMOD_SDF_LSB (2 << 5)
87#define S3C2412_IISMOD_SDF_MASK (3 << 5)
88#define S3C2412_IISMOD_RCLK_256FS (0 << 3)
89#define S3C2412_IISMOD_RCLK_512FS (1 << 3)
90#define S3C2412_IISMOD_RCLK_384FS (2 << 3)
91#define S3C2412_IISMOD_RCLK_768FS (3 << 3)
92#define S3C2412_IISMOD_RCLK_MASK (3 << 3)
93#define S3C2412_IISMOD_BCLK_32FS (0 << 1)
94#define S3C2412_IISMOD_BCLK_48FS (1 << 1)
95#define S3C2412_IISMOD_BCLK_16FS (2 << 1)
96#define S3C2412_IISMOD_BCLK_24FS (3 << 1)
97#define S3C2412_IISMOD_BCLK_MASK (3 << 1)
98#define S3C2412_IISMOD_8BIT (1 << 0)
99
100#define S3C64XX_IISMOD_CDCLKCON (1 << 12)
101
102#define S3C2412_IISPSR_PSREN (1 << 15)
103
104#define S3C64XX_IISFIC_TX2COUNT(x) (((x) >> 24) & 0xf)
105#define S3C64XX_IISFIC_TX1COUNT(x) (((x) >> 16) & 0xf)
106
107#define S3C2412_IISFIC_TXFLUSH (1 << 15)
108#define S3C2412_IISFIC_RXFLUSH (1 << 7)
109#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf)
110#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf)
111
112#define S5PC1XX_IISFICS_TXFLUSH (1 << 15)
113#define S5PC1XX_IISFICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
114
115#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 88515946b6c0..13311c8cf965 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -16,24 +16,17 @@
16 * option) any later version. 16 * option) any later version.
17 */ 17 */
18 18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/device.h>
22#include <linux/delay.h> 19#include <linux/delay.h>
23#include <linux/clk.h> 20#include <linux/clk.h>
24#include <linux/kernel.h>
25#include <linux/io.h> 21#include <linux/io.h>
26 22
27#include <sound/core.h>
28#include <sound/pcm.h> 23#include <sound/pcm.h>
29#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
30#include <sound/initval.h>
31#include <sound/soc.h> 25#include <sound/soc.h>
32 26
33#include <plat/regs-s3c2412-iis.h>
34
35#include <mach/dma.h> 27#include <mach/dma.h>
36 28
29#include "regs-i2s-v2.h"
37#include "s3c-i2s-v2.h" 30#include "s3c-i2s-v2.h"
38#include "s3c-dma.h" 31#include "s3c-dma.h"
39 32
@@ -272,35 +265,14 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
272 iismod = readl(i2s->regs + S3C2412_IISMOD); 265 iismod = readl(i2s->regs + S3C2412_IISMOD);
273 pr_debug("hw_params r: IISMOD: %x \n", iismod); 266 pr_debug("hw_params r: IISMOD: %x \n", iismod);
274 267
275#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
276#define IISMOD_MASTER_MASK S3C2412_IISMOD_MASTER_MASK
277#define IISMOD_SLAVE S3C2412_IISMOD_SLAVE
278#define IISMOD_MASTER S3C2412_IISMOD_MASTER_INTERNAL
279#endif
280
281#if defined(CONFIG_PLAT_S3C64XX)
282/* From Rev1.1 datasheet, we have two master and two slave modes:
283 * IMS[11:10]:
284 * 00 = master mode, fed from PCLK
285 * 01 = master mode, fed from CLKAUDIO
286 * 10 = slave mode, using PCLK
287 * 11 = slave mode, using I2SCLK
288 */
289#define IISMOD_MASTER_MASK (1 << 11)
290#define IISMOD_SLAVE (1 << 11)
291#define IISMOD_MASTER (0 << 11)
292#endif
293
294 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 268 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
295 case SND_SOC_DAIFMT_CBM_CFM: 269 case SND_SOC_DAIFMT_CBM_CFM:
296 i2s->master = 0; 270 i2s->master = 0;
297 iismod &= ~IISMOD_MASTER_MASK; 271 iismod |= S3C2412_IISMOD_SLAVE;
298 iismod |= IISMOD_SLAVE;
299 break; 272 break;
300 case SND_SOC_DAIFMT_CBS_CFS: 273 case SND_SOC_DAIFMT_CBS_CFS:
301 i2s->master = 1; 274 i2s->master = 1;
302 iismod &= ~IISMOD_MASTER_MASK; 275 iismod &= ~S3C2412_IISMOD_SLAVE;
303 iismod |= IISMOD_MASTER;
304 break; 276 break;
305 default: 277 default:
306 pr_err("unknwon master/slave format\n"); 278 pr_err("unknwon master/slave format\n");
@@ -332,7 +304,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
332 return 0; 304 return 0;
333} 305}
334 306
335static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, 307static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream,
336 struct snd_pcm_hw_params *params, 308 struct snd_pcm_hw_params *params,
337 struct snd_soc_dai *socdai) 309 struct snd_soc_dai *socdai)
338{ 310{
@@ -355,37 +327,67 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
355 iismod = readl(i2s->regs + S3C2412_IISMOD); 327 iismod = readl(i2s->regs + S3C2412_IISMOD);
356 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); 328 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
357 329
358#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) 330 iismod &= ~S3C64XX_IISMOD_BLC_MASK;
331 /* Sample size */
359 switch (params_format(params)) { 332 switch (params_format(params)) {
360 case SNDRV_PCM_FORMAT_S8: 333 case SNDRV_PCM_FORMAT_S8:
361 iismod |= S3C2412_IISMOD_8BIT; 334 iismod |= S3C64XX_IISMOD_BLC_8BIT;
362 break; 335 break;
363 case SNDRV_PCM_FORMAT_S16_LE: 336 case SNDRV_PCM_FORMAT_S16_LE:
364 iismod &= ~S3C2412_IISMOD_8BIT; 337 break;
338 case SNDRV_PCM_FORMAT_S24_LE:
339 iismod |= S3C64XX_IISMOD_BLC_24BIT;
365 break; 340 break;
366 } 341 }
367#endif
368 342
369#ifdef CONFIG_PLAT_S3C64XX 343 writel(iismod, i2s->regs + S3C2412_IISMOD);
370 iismod &= ~(S3C64XX_IISMOD_BLC_MASK | S3C2412_IISMOD_BCLK_MASK); 344 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
371 /* Sample size */ 345
372 switch (params_format(params)) { 346 return 0;
373 case SNDRV_PCM_FORMAT_S8: 347}
374 /* 8 bit sample, 16fs BCLK */ 348
375 iismod |= (S3C64XX_IISMOD_BLC_8BIT | S3C2412_IISMOD_BCLK_16FS); 349static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai,
350 int clk_id, unsigned int freq, int dir)
351{
352 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
353 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
354
355 pr_debug("Entered %s\n", __func__);
356 pr_debug("%s r: IISMOD: %x\n", __func__, iismod);
357
358 switch (clk_id) {
359 case S3C_I2SV2_CLKSRC_PCLK:
360 iismod &= ~S3C2412_IISMOD_IMS_SYSMUX;
376 break; 361 break;
377 case SNDRV_PCM_FORMAT_S16_LE: 362
378 /* 16 bit sample, 32fs BCLK */ 363 case S3C_I2SV2_CLKSRC_AUDIOBUS:
364 iismod |= S3C2412_IISMOD_IMS_SYSMUX;
379 break; 365 break;
380 case SNDRV_PCM_FORMAT_S24_LE: 366
381 /* 24 bit sample, 48fs BCLK */ 367 case S3C_I2SV2_CLKSRC_CDCLK:
382 iismod |= (S3C64XX_IISMOD_BLC_24BIT | S3C2412_IISMOD_BCLK_48FS); 368 /* Error if controller doesn't have the CDCLKCON bit */
369 if (!(i2s->feature & S3C_FEATURE_CDCLKCON))
370 return -EINVAL;
371
372 switch (dir) {
373 case SND_SOC_CLOCK_IN:
374 iismod |= S3C64XX_IISMOD_CDCLKCON;
375 break;
376 case SND_SOC_CLOCK_OUT:
377 iismod &= ~S3C64XX_IISMOD_CDCLKCON;
378 break;
379 default:
380 return -EINVAL;
381 }
383 break; 382 break;
383
384 default:
385 return -EINVAL;
384 } 386 }
385#endif
386 387
387 writel(iismod, i2s->regs + S3C2412_IISMOD); 388 writel(iismod, i2s->regs + S3C2412_IISMOD);
388 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); 389 pr_debug("%s w: IISMOD: %x\n", __func__, iismod);
390
389 return 0; 391 return 0;
390} 392}
391 393
@@ -472,29 +474,25 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
472 474
473 switch (div_id) { 475 switch (div_id) {
474 case S3C_I2SV2_DIV_BCLK: 476 case S3C_I2SV2_DIV_BCLK:
475 if (div > 3) { 477 switch (div) {
476 /* convert value to bit field */ 478 case 16:
477 479 div = S3C2412_IISMOD_BCLK_16FS;
478 switch (div) { 480 break;
479 case 16:
480 div = S3C2412_IISMOD_BCLK_16FS;
481 break;
482 481
483 case 32: 482 case 32:
484 div = S3C2412_IISMOD_BCLK_32FS; 483 div = S3C2412_IISMOD_BCLK_32FS;
485 break; 484 break;
486 485
487 case 24: 486 case 24:
488 div = S3C2412_IISMOD_BCLK_24FS; 487 div = S3C2412_IISMOD_BCLK_24FS;
489 break; 488 break;
490 489
491 case 48: 490 case 48:
492 div = S3C2412_IISMOD_BCLK_48FS; 491 div = S3C2412_IISMOD_BCLK_48FS;
493 break; 492 break;
494 493
495 default: 494 default:
496 return -EINVAL; 495 return -EINVAL;
497 }
498 } 496 }
499 497
500 reg = readl(i2s->regs + S3C2412_IISMOD); 498 reg = readl(i2s->regs + S3C2412_IISMOD);
@@ -505,29 +503,25 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
505 break; 503 break;
506 504
507 case S3C_I2SV2_DIV_RCLK: 505 case S3C_I2SV2_DIV_RCLK:
508 if (div > 3) { 506 switch (div) {
509 /* convert value to bit field */ 507 case 256:
510 508 div = S3C2412_IISMOD_RCLK_256FS;
511 switch (div) { 509 break;
512 case 256:
513 div = S3C2412_IISMOD_RCLK_256FS;
514 break;
515 510
516 case 384: 511 case 384:
517 div = S3C2412_IISMOD_RCLK_384FS; 512 div = S3C2412_IISMOD_RCLK_384FS;
518 break; 513 break;
519 514
520 case 512: 515 case 512:
521 div = S3C2412_IISMOD_RCLK_512FS; 516 div = S3C2412_IISMOD_RCLK_512FS;
522 break; 517 break;
523 518
524 case 768: 519 case 768:
525 div = S3C2412_IISMOD_RCLK_768FS; 520 div = S3C2412_IISMOD_RCLK_768FS;
526 break; 521 break;
527 522
528 default: 523 default:
529 return -EINVAL; 524 return -EINVAL;
530 }
531 } 525 }
532 526
533 reg = readl(i2s->regs + S3C2412_IISMOD); 527 reg = readl(i2s->regs + S3C2412_IISMOD);
@@ -553,6 +547,33 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
553 return 0; 547 return 0;
554} 548}
555 549
550static snd_pcm_sframes_t s3c2412_i2s_delay(struct snd_pcm_substream *substream,
551 struct snd_soc_dai *dai)
552{
553 struct s3c_i2sv2_info *i2s = to_info(dai);
554 u32 reg = readl(i2s->regs + S3C2412_IISFIC);
555 snd_pcm_sframes_t delay;
556
557 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
558 delay = S3C2412_IISFIC_TXCOUNT(reg);
559 else
560 delay = S3C2412_IISFIC_RXCOUNT(reg);
561
562 return delay;
563}
564
565struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai)
566{
567 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
568 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
569
570 if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
571 return i2s->iis_cclk;
572 else
573 return i2s->iis_pclk;
574}
575EXPORT_SYMBOL_GPL(s3c_i2sv2_get_clock);
576
556/* default table of all avaialable root fs divisors */ 577/* default table of all avaialable root fs divisors */
557static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; 578static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 };
558 579
@@ -735,9 +756,15 @@ int s3c_i2sv2_register_dai(struct snd_soc_dai *dai)
735 struct snd_soc_dai_ops *ops = dai->ops; 756 struct snd_soc_dai_ops *ops = dai->ops;
736 757
737 ops->trigger = s3c2412_i2s_trigger; 758 ops->trigger = s3c2412_i2s_trigger;
738 ops->hw_params = s3c2412_i2s_hw_params; 759 if (!ops->hw_params)
760 ops->hw_params = s3c_i2sv2_hw_params;
739 ops->set_fmt = s3c2412_i2s_set_fmt; 761 ops->set_fmt = s3c2412_i2s_set_fmt;
740 ops->set_clkdiv = s3c2412_i2s_set_clkdiv; 762 ops->set_clkdiv = s3c2412_i2s_set_clkdiv;
763 ops->set_sysclk = s3c_i2sv2_set_sysclk;
764
765 /* Allow overriding by (for example) IISv4 */
766 if (!ops->delay)
767 ops->delay = s3c2412_i2s_delay;
741 768
742 dai->suspend = s3c2412_i2s_suspend; 769 dai->suspend = s3c2412_i2s_suspend;
743 dai->resume = s3c2412_i2s_resume; 770 dai->resume = s3c2412_i2s_resume;
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/s3c24xx/s3c-i2s-v2.h
index ecf8eaaed1db..766f43a13d8b 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.h
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.h
@@ -25,10 +25,20 @@
25#define S3C_I2SV2_DIV_RCLK (2) 25#define S3C_I2SV2_DIV_RCLK (2)
26#define S3C_I2SV2_DIV_PRESCALER (3) 26#define S3C_I2SV2_DIV_PRESCALER (3)
27 27
28#define S3C_I2SV2_CLKSRC_PCLK 0
29#define S3C_I2SV2_CLKSRC_AUDIOBUS 1
30#define S3C_I2SV2_CLKSRC_CDCLK 2
31
32/* Set this flag for I2S controllers that have the bit IISMOD[12]
33 * bridge/break RCLK signal and external Xi2sCDCLK pin.
34 */
35#define S3C_FEATURE_CDCLKCON (1 << 0)
36
28/** 37/**
29 * struct s3c_i2sv2_info - S3C I2S-V2 information 38 * struct s3c_i2sv2_info - S3C I2S-V2 information
30 * @dev: The parent device passed to use from the probe. 39 * @dev: The parent device passed to use from the probe.
31 * @regs: The pointer to the device registe block. 40 * @regs: The pointer to the device registe block.
41 * @feature: Set of bit-flags indicating features of the controller.
32 * @master: True if the I2S core is the I2S bit clock master. 42 * @master: True if the I2S core is the I2S bit clock master.
33 * @dma_playback: DMA information for playback channel. 43 * @dma_playback: DMA information for playback channel.
34 * @dma_capture: DMA information for capture channel. 44 * @dma_capture: DMA information for capture channel.
@@ -43,9 +53,10 @@ struct s3c_i2sv2_info {
43 struct device *dev; 53 struct device *dev;
44 void __iomem *regs; 54 void __iomem *regs;
45 55
56 u32 feature;
57
46 struct clk *iis_pclk; 58 struct clk *iis_pclk;
47 struct clk *iis_cclk; 59 struct clk *iis_cclk;
48 struct clk *iis_clk;
49 60
50 unsigned char master; 61 unsigned char master;
51 62
@@ -57,6 +68,8 @@ struct s3c_i2sv2_info {
57 u32 suspend_iispsr; 68 u32 suspend_iispsr;
58}; 69};
59 70
71extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai);
72
60struct s3c_i2sv2_rate_calc { 73struct s3c_i2sv2_rate_calc {
61 unsigned int clk_div; /* for prescaler */ 74 unsigned int clk_div; /* for prescaler */
62 unsigned int fs_div; /* for root frame clock */ 75 unsigned int fs_div; /* for root frame clock */
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index 359e59346ba2..709adef9d043 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -32,12 +32,11 @@
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <mach/hardware.h> 33#include <mach/hardware.h>
34 34
35#include <plat/regs-s3c2412-iis.h>
36
37#include <mach/regs-gpio.h> 35#include <mach/regs-gpio.h>
38#include <mach/dma.h> 36#include <mach/dma.h>
39 37
40#include "s3c-dma.h" 38#include "s3c-dma.h"
39#include "regs-i2s-v2.h"
41#include "s3c2412-i2s.h" 40#include "s3c2412-i2s.h"
42 41
43#define S3C2412_I2S_DEBUG 0 42#define S3C2412_I2S_DEBUG 0
@@ -66,44 +65,11 @@ static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
66 65
67static struct s3c_i2sv2_info s3c2412_i2s; 66static struct s3c_i2sv2_info s3c2412_i2s;
68 67
69/* 68static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
70 * Set S3C2412 Clock source
71 */
72static int s3c2412_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
73 int clk_id, unsigned int freq, int dir)
74{ 69{
75 u32 iismod = readl(s3c2412_i2s.regs + S3C2412_IISMOD); 70 return cpu_dai->private_data;
76
77 pr_debug("%s(%p, %d, %u, %d)\n", __func__, cpu_dai, clk_id,
78 freq, dir);
79
80 switch (clk_id) {
81 case S3C2412_CLKSRC_PCLK:
82 s3c2412_i2s.master = 1;
83 iismod &= ~S3C2412_IISMOD_MASTER_MASK;
84 iismod |= S3C2412_IISMOD_MASTER_INTERNAL;
85 break;
86 case S3C2412_CLKSRC_I2SCLK:
87 s3c2412_i2s.master = 0;
88 iismod &= ~S3C2412_IISMOD_MASTER_MASK;
89 iismod |= S3C2412_IISMOD_MASTER_EXTERNAL;
90 break;
91 default:
92 return -EINVAL;
93 }
94
95 writel(iismod, s3c2412_i2s.regs + S3C2412_IISMOD);
96 return 0;
97} 71}
98 72
99
100struct clk *s3c2412_get_iisclk(void)
101{
102 return s3c2412_i2s.iis_clk;
103}
104EXPORT_SYMBOL_GPL(s3c2412_get_iisclk);
105
106
107static int s3c2412_i2s_probe(struct platform_device *pdev, 73static int s3c2412_i2s_probe(struct platform_device *pdev,
108 struct snd_soc_dai *dai) 74 struct snd_soc_dai *dai)
109{ 75{
@@ -142,13 +108,48 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
142 return 0; 108 return 0;
143} 109}
144 110
111static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
112 struct snd_pcm_hw_params *params,
113 struct snd_soc_dai *cpu_dai)
114{
115 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
116 struct s3c_dma_params *dma_data;
117 u32 iismod;
118
119 pr_debug("Entered %s\n", __func__);
120
121 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
122 dma_data = i2s->dma_playback;
123 else
124 dma_data = i2s->dma_capture;
125
126 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
127
128 iismod = readl(i2s->regs + S3C2412_IISMOD);
129 pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
130
131 switch (params_format(params)) {
132 case SNDRV_PCM_FORMAT_S8:
133 iismod |= S3C2412_IISMOD_8BIT;
134 break;
135 case SNDRV_PCM_FORMAT_S16_LE:
136 iismod &= ~S3C2412_IISMOD_8BIT;
137 break;
138 }
139
140 writel(iismod, i2s->regs + S3C2412_IISMOD);
141 pr_debug("%s: w: IISMOD: %x\n", __func__, iismod);
142
143 return 0;
144}
145
145#define S3C2412_I2S_RATES \ 146#define S3C2412_I2S_RATES \
146 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ 147 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
147 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 148 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
148 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 149 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
149 150
150static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { 151static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = {
151 .set_sysclk = s3c2412_i2s_set_sysclk, 152 .hw_params = s3c2412_i2s_hw_params,
152}; 153};
153 154
154struct snd_soc_dai s3c2412_i2s_dai = { 155struct snd_soc_dai s3c2412_i2s_dai = {
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/s3c24xx/s3c2412-i2s.h
index 92848e54be16..0b5686b4d5c3 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.h
+++ b/sound/soc/s3c24xx/s3c2412-i2s.h
@@ -21,10 +21,8 @@
21#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK 21#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK
22#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER 22#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
23 23
24#define S3C2412_CLKSRC_PCLK (0) 24#define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
25#define S3C2412_CLKSRC_I2SCLK (1) 25#define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS
26
27extern struct clk *s3c2412_get_iisclk(void);
28 26
29extern struct snd_soc_dai s3c2412_i2s_dai; 27extern struct snd_soc_dai s3c2412_i2s_dai;
30 28
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
new file mode 100644
index 000000000000..06db130030a1
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
@@ -0,0 +1,209 @@
1/* sound/soc/s3c24xx/s3c64xx-i2s-v4.c
2 *
3 * ALSA SoC Audio Layer - S3C64XX I2Sv4 driver
4 * Copyright (c) 2010 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/gpio.h>
14#include <linux/io.h>
15
16#include <sound/soc.h>
17#include <sound/pcm_params.h>
18
19#include <mach/gpio-bank-c.h>
20#include <mach/gpio-bank-h.h>
21#include <plat/gpio-cfg.h>
22
23#include <mach/map.h>
24#include <mach/dma.h>
25
26#include "s3c-dma.h"
27#include "regs-i2s-v2.h"
28#include "s3c64xx-i2s.h"
29
30static struct s3c2410_dma_client s3c64xx_dma_client_out = {
31 .name = "I2Sv4 PCM Stereo out"
32};
33
34static struct s3c2410_dma_client s3c64xx_dma_client_in = {
35 .name = "I2Sv4 PCM Stereo in"
36};
37
38static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out;
39static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in;
40static struct s3c_i2sv2_info s3c64xx_i2sv4;
41
42struct snd_soc_dai s3c64xx_i2s_v4_dai;
43EXPORT_SYMBOL_GPL(s3c64xx_i2s_v4_dai);
44
45static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
46{
47 return cpu_dai->private_data;
48}
49
50static int s3c64xx_i2sv4_probe(struct platform_device *pdev,
51 struct snd_soc_dai *dai)
52{
53 /* configure GPIO for i2s port */
54 s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0);
55 s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1);
56 s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2);
57 s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK);
58 s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK);
59 s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK);
60 s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI);
61
62 return 0;
63}
64
65static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params,
67 struct snd_soc_dai *cpu_dai)
68{
69 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
70 struct s3c_dma_params *dma_data;
71 u32 iismod;
72
73 dev_dbg(cpu_dai->dev, "Entered %s\n", __func__);
74
75 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
76 dma_data = i2s->dma_playback;
77 else
78 dma_data = i2s->dma_capture;
79
80 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
81
82 iismod = readl(i2s->regs + S3C2412_IISMOD);
83 dev_dbg(cpu_dai->dev, "%s: r: IISMOD: %x\n", __func__, iismod);
84
85 iismod &= ~S3C64XX_IISMOD_BLC_MASK;
86 switch (params_format(params)) {
87 case SNDRV_PCM_FORMAT_S8:
88 iismod |= S3C64XX_IISMOD_BLC_8BIT;
89 break;
90 case SNDRV_PCM_FORMAT_S16_LE:
91 break;
92 case SNDRV_PCM_FORMAT_S24_LE:
93 iismod |= S3C64XX_IISMOD_BLC_24BIT;
94 break;
95 }
96
97 writel(iismod, i2s->regs + S3C2412_IISMOD);
98 dev_dbg(cpu_dai->dev, "%s: w: IISMOD: %x\n", __func__, iismod);
99
100 return 0;
101}
102
103static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = {
104 .hw_params = s3c_i2sv4_hw_params,
105};
106
107static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev)
108{
109 struct s3c_i2sv2_info *i2s;
110 struct snd_soc_dai *dai;
111 int ret;
112
113 i2s = &s3c64xx_i2sv4;
114 dai = &s3c64xx_i2s_v4_dai;
115
116 if (dai->dev) {
117 dev_dbg(dai->dev, "%s: \
118 I2Sv4 instance already registered!\n", __func__);
119 return -EBUSY;
120 }
121
122 dai->dev = &pdev->dev;
123 dai->name = "s3c64xx-i2s-v4";
124 dai->id = 0;
125 dai->symmetric_rates = 1;
126 dai->playback.channels_min = 2;
127 dai->playback.channels_max = 2;
128 dai->playback.rates = S3C64XX_I2S_RATES;
129 dai->playback.formats = S3C64XX_I2S_FMTS;
130 dai->capture.channels_min = 2;
131 dai->capture.channels_max = 2;
132 dai->capture.rates = S3C64XX_I2S_RATES;
133 dai->capture.formats = S3C64XX_I2S_FMTS;
134 dai->probe = s3c64xx_i2sv4_probe;
135 dai->ops = &s3c64xx_i2sv4_dai_ops;
136
137 i2s->feature |= S3C_FEATURE_CDCLKCON;
138
139 i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in;
140 i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out;
141
142 i2s->dma_capture->channel = DMACH_HSI_I2SV40_RX;
143 i2s->dma_capture->dma_addr = S3C64XX_PA_IISV4 + S3C2412_IISRXD;
144 i2s->dma_playback->channel = DMACH_HSI_I2SV40_TX;
145 i2s->dma_playback->dma_addr = S3C64XX_PA_IISV4 + S3C2412_IISTXD;
146
147 i2s->dma_capture->client = &s3c64xx_dma_client_in;
148 i2s->dma_capture->dma_size = 4;
149 i2s->dma_playback->client = &s3c64xx_dma_client_out;
150 i2s->dma_playback->dma_size = 4;
151
152 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
153 if (IS_ERR(i2s->iis_cclk)) {
154 dev_err(&pdev->dev, "failed to get audio-bus\n");
155 ret = PTR_ERR(i2s->iis_cclk);
156 goto err;
157 }
158
159 clk_enable(i2s->iis_cclk);
160
161 ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
162 if (ret)
163 goto err_clk;
164
165 ret = s3c_i2sv2_register_dai(dai);
166 if (ret != 0)
167 goto err_i2sv2;
168
169 return 0;
170
171err_i2sv2:
172 /* Not implemented for I2Sv2 core yet */
173err_clk:
174 clk_put(i2s->iis_cclk);
175err:
176 return ret;
177}
178
179static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev)
180{
181 dev_err(&pdev->dev, "Device removal not yet supported\n");
182 return 0;
183}
184
185static struct platform_driver s3c64xx_i2sv4_driver = {
186 .probe = s3c64xx_i2sv4_dev_probe,
187 .remove = s3c64xx_i2sv4_dev_remove,
188 .driver = {
189 .name = "s3c64xx-iis-v4",
190 .owner = THIS_MODULE,
191 },
192};
193
194static int __init s3c64xx_i2sv4_init(void)
195{
196 return platform_driver_register(&s3c64xx_i2sv4_driver);
197}
198module_init(s3c64xx_i2sv4_init);
199
200static void __exit s3c64xx_i2sv4_exit(void)
201{
202 platform_driver_unregister(&s3c64xx_i2sv4_driver);
203}
204module_exit(s3c64xx_i2sv4_exit);
205
206/* Module information */
207MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
208MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface");
209MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index a72c251401ac..1d85cb85a7d2 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -12,16 +12,12 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/device.h>
18#include <linux/clk.h> 15#include <linux/clk.h>
19#include <linux/gpio.h> 16#include <linux/gpio.h>
20#include <linux/io.h> 17#include <linux/io.h>
21 18
22#include <sound/soc.h> 19#include <sound/soc.h>
23 20
24#include <plat/regs-s3c2412-iis.h>
25#include <mach/gpio-bank-d.h> 21#include <mach/gpio-bank-d.h>
26#include <mach/gpio-bank-e.h> 22#include <mach/gpio-bank-e.h>
27#include <plat/gpio-cfg.h> 23#include <plat/gpio-cfg.h>
@@ -30,6 +26,7 @@
30#include <mach/dma.h> 26#include <mach/dma.h>
31 27
32#include "s3c-dma.h" 28#include "s3c-dma.h"
29#include "regs-i2s-v2.h"
33#include "s3c64xx-i2s.h" 30#include "s3c64xx-i2s.h"
34 31
35/* The value should be set to maximum of the total number 32/* The value should be set to maximum of the total number
@@ -57,55 +54,6 @@ static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
57 return cpu_dai->private_data; 54 return cpu_dai->private_data;
58} 55}
59 56
60static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
61 int clk_id, unsigned int freq, int dir)
62{
63 struct s3c_i2sv2_info *i2s = to_info(cpu_dai);
64 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
65
66 switch (clk_id) {
67 case S3C64XX_CLKSRC_PCLK:
68 iismod &= ~S3C64XX_IISMOD_IMS_SYSMUX;
69 break;
70
71 case S3C64XX_CLKSRC_MUX:
72 iismod |= S3C64XX_IISMOD_IMS_SYSMUX;
73 break;
74
75 case S3C64XX_CLKSRC_CDCLK:
76 switch (dir) {
77 case SND_SOC_CLOCK_IN:
78 iismod |= S3C64XX_IISMOD_CDCLKCON;
79 break;
80 case SND_SOC_CLOCK_OUT:
81 iismod &= ~S3C64XX_IISMOD_CDCLKCON;
82 break;
83 default:
84 return -EINVAL;
85 }
86 break;
87
88 default:
89 return -EINVAL;
90 }
91
92 writel(iismod, i2s->regs + S3C2412_IISMOD);
93
94 return 0;
95}
96
97struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
98{
99 struct s3c_i2sv2_info *i2s = to_info(dai);
100 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
101
102 if (iismod & S3C64XX_IISMOD_IMS_SYSMUX)
103 return i2s->iis_cclk;
104 else
105 return i2s->iis_pclk;
106}
107EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
108
109static int s3c64xx_i2s_probe(struct platform_device *pdev, 57static int s3c64xx_i2s_probe(struct platform_device *pdev,
110 struct snd_soc_dai *dai) 58 struct snd_soc_dai *dai)
111{ 59{
@@ -130,18 +78,7 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev,
130} 78}
131 79
132 80
133#define S3C64XX_I2S_RATES \ 81static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops;
134 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
135 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
136 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
137
138#define S3C64XX_I2S_FMTS \
139 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
140 SNDRV_PCM_FMTBIT_S24_LE)
141
142static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
143 .set_sysclk = s3c64xx_i2s_set_sysclk,
144};
145 82
146static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) 83static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
147{ 84{
@@ -171,6 +108,8 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
171 dai->probe = s3c64xx_i2s_probe; 108 dai->probe = s3c64xx_i2s_probe;
172 dai->ops = &s3c64xx_i2s_dai_ops; 109 dai->ops = &s3c64xx_i2s_dai_ops;
173 110
111 i2s->feature |= S3C_FEATURE_CDCLKCON;
112
174 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; 113 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
175 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; 114 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
176 115
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index abe7253b55fc..7a40f43d1d51 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -23,12 +23,20 @@ struct clk;
23#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK 23#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK
24#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER 24#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
25 25
26#define S3C64XX_CLKSRC_PCLK (0) 26#define S3C64XX_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
27#define S3C64XX_CLKSRC_MUX (1) 27#define S3C64XX_CLKSRC_MUX S3C_I2SV2_CLKSRC_AUDIOBUS
28#define S3C64XX_CLKSRC_CDCLK (2) 28#define S3C64XX_CLKSRC_CDCLK S3C_I2SV2_CLKSRC_CDCLK
29 29
30extern struct snd_soc_dai s3c64xx_i2s_dai[]; 30#define S3C64XX_I2S_RATES \
31 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
32 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
33 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
34
35#define S3C64XX_I2S_FMTS \
36 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
37 SNDRV_PCM_FMTBIT_S24_LE)
31 38
32extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai); 39extern struct snd_soc_dai s3c64xx_i2s_dai[];
40extern struct snd_soc_dai s3c64xx_i2s_v4_dai;
33 41
34#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ 42#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c
index efe4901213a3..07e8e51d10d6 100644
--- a/sound/soc/s3c24xx/smdk64xx_wm8580.c
+++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c
@@ -22,8 +22,6 @@
22#include "s3c-dma.h" 22#include "s3c-dma.h"
23#include "s3c64xx-i2s.h" 23#include "s3c64xx-i2s.h"
24 24
25#define S3C64XX_I2S_V4 2
26
27/* SMDK64XX has a 12MHZ crystal attached to WM8580 */ 25/* SMDK64XX has a 12MHZ crystal attached to WM8580 */
28#define SMDK64XX_WM8580_FREQ 12000000 26#define SMDK64XX_WM8580_FREQ 12000000
29 27
@@ -215,7 +213,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = {
215{ /* Primary Playback i/f */ 213{ /* Primary Playback i/f */
216 .name = "WM8580 PAIF RX", 214 .name = "WM8580 PAIF RX",
217 .stream_name = "Playback", 215 .stream_name = "Playback",
218 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4], 216 .cpu_dai = &s3c64xx_i2s_v4_dai,
219 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX], 217 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX],
220 .init = smdk64xx_wm8580_init_paifrx, 218 .init = smdk64xx_wm8580_init_paifrx,
221 .ops = &smdk64xx_ops, 219 .ops = &smdk64xx_ops,
@@ -223,7 +221,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = {
223{ /* Primary Capture i/f */ 221{ /* Primary Capture i/f */
224 .name = "WM8580 PAIF TX", 222 .name = "WM8580 PAIF TX",
225 .stream_name = "Capture", 223 .stream_name = "Capture",
226 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4], 224 .cpu_dai = &s3c64xx_i2s_v4_dai,
227 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX], 225 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX],
228 .init = smdk64xx_wm8580_init_paiftx, 226 .init = smdk64xx_wm8580_init_paiftx,
229 .ops = &smdk64xx_ops, 227 .ops = &smdk64xx_ops,
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index f07f6d8b93e1..a1d14bc3c76f 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -1,5 +1,5 @@
1menu "SoC Audio support for SuperH" 1menu "SoC Audio support for SuperH"
2 depends on SUPERH 2 depends on SUPERH || ARCH_SHMOBILE
3 3
4config SND_SOC_PCM_SH7760 4config SND_SOC_PCM_SH7760
5 tristate "SoC Audio support for Renesas SH7760" 5 tristate "SoC Audio support for Renesas SH7760"
@@ -22,7 +22,6 @@ config SND_SOC_SH4_SSI
22 22
23config SND_SOC_SH4_FSI 23config SND_SOC_SH4_FSI
24 tristate "SH4 FSI support" 24 tristate "SH4 FSI support"
25 depends on CPU_SUBTYPE_SH7724
26 help 25 help
27 This option enables FSI sound support 26 This option enables FSI sound support
28 27
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index 5263ab18f827..be018542314e 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -22,11 +22,25 @@
22#include <sound/sh_fsi.h> 22#include <sound/sh_fsi.h>
23#include <../sound/soc/codecs/ak4642.h> 23#include <../sound/soc/codecs/ak4642.h>
24 24
25static int fsi_ak4642_dai_init(struct snd_soc_codec *codec)
26{
27 int ret;
28
29 ret = snd_soc_dai_set_fmt(&ak4642_dai, SND_SOC_DAIFMT_CBM_CFM);
30 if (ret < 0)
31 return ret;
32
33 ret = snd_soc_dai_set_sysclk(&ak4642_dai, 0, 11289600, 0);
34
35 return ret;
36}
37
25static struct snd_soc_dai_link fsi_dai_link = { 38static struct snd_soc_dai_link fsi_dai_link = {
26 .name = "AK4642", 39 .name = "AK4642",
27 .stream_name = "AK4642", 40 .stream_name = "AK4642",
28 .cpu_dai = &fsi_soc_dai[0], /* fsi */ 41 .cpu_dai = &fsi_soc_dai[0], /* fsi */
29 .codec_dai = &ak4642_dai, 42 .codec_dai = &ak4642_dai,
43 .init = fsi_ak4642_dai_init,
30 .ops = NULL, 44 .ops = NULL,
31}; 45};
32 46
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 8dc966f45c36..3396a0db06ba 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -41,14 +41,19 @@
41#define MUTE_ST 0x0028 41#define MUTE_ST 0x0028
42#define REG_END MUTE_ST 42#define REG_END MUTE_ST
43 43
44
45#define CPU_INT_ST 0x01F4
46#define CPU_IEMSK 0x01F8
47#define CPU_IMSK 0x01FC
44#define INT_ST 0x0200 48#define INT_ST 0x0200
45#define IEMSK 0x0204 49#define IEMSK 0x0204
46#define IMSK 0x0208 50#define IMSK 0x0208
47#define MUTE 0x020C 51#define MUTE 0x020C
48#define CLK_RST 0x0210 52#define CLK_RST 0x0210
49#define SOFT_RST 0x0214 53#define SOFT_RST 0x0214
50#define MREG_START INT_ST 54#define FIFO_SZ 0x0218
51#define MREG_END SOFT_RST 55#define MREG_START CPU_INT_ST
56#define MREG_END FIFO_SZ
52 57
53/* DO_FMT */ 58/* DO_FMT */
54/* DI_FMT */ 59/* DI_FMT */
@@ -80,6 +85,17 @@
80#define INT_A_IN (1 << 4) 85#define INT_A_IN (1 << 4)
81#define INT_A_OUT (1 << 0) 86#define INT_A_OUT (1 << 0)
82 87
88/* SOFT_RST */
89#define PBSR (1 << 12) /* Port B Software Reset */
90#define PASR (1 << 8) /* Port A Software Reset */
91#define IR (1 << 4) /* Interrupt Reset */
92#define FSISR (1 << 0) /* Software Reset */
93
94/* FIFO_SZ */
95#define OUT_SZ_MASK 0x7
96#define BO_SZ_SHIFT 8
97#define AO_SZ_SHIFT 0
98
83#define FSI_RATES SNDRV_PCM_RATE_8000_96000 99#define FSI_RATES SNDRV_PCM_RATE_8000_96000
84 100
85#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 101#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
@@ -105,11 +121,18 @@ struct fsi_priv {
105 int periods; 121 int periods;
106}; 122};
107 123
124struct fsi_regs {
125 u32 int_st;
126 u32 iemsk;
127 u32 imsk;
128};
129
108struct fsi_master { 130struct fsi_master {
109 void __iomem *base; 131 void __iomem *base;
110 int irq; 132 int irq;
111 struct fsi_priv fsia; 133 struct fsi_priv fsia;
112 struct fsi_priv fsib; 134 struct fsi_priv fsib;
135 struct fsi_regs *regs;
113 struct sh_fsi_platform_info *info; 136 struct sh_fsi_platform_info *info;
114 spinlock_t lock; 137 spinlock_t lock;
115}; 138};
@@ -317,7 +340,7 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
317/************************************************************************ 340/************************************************************************
318 341
319 342
320 ctrl function 343 irq function
321 344
322 345
323************************************************************************/ 346************************************************************************/
@@ -326,8 +349,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
326 u32 data = fsi_port_ab_io_bit(fsi, is_play); 349 u32 data = fsi_port_ab_io_bit(fsi, is_play);
327 struct fsi_master *master = fsi_get_master(fsi); 350 struct fsi_master *master = fsi_get_master(fsi);
328 351
329 fsi_master_mask_set(master, IMSK, data, data); 352 fsi_master_mask_set(master, master->regs->imsk, data, data);
330 fsi_master_mask_set(master, IEMSK, data, data); 353 fsi_master_mask_set(master, master->regs->iemsk, data, data);
331} 354}
332 355
333static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 356static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
@@ -335,10 +358,39 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
335 u32 data = fsi_port_ab_io_bit(fsi, is_play); 358 u32 data = fsi_port_ab_io_bit(fsi, is_play);
336 struct fsi_master *master = fsi_get_master(fsi); 359 struct fsi_master *master = fsi_get_master(fsi);
337 360
338 fsi_master_mask_set(master, IMSK, data, 0); 361 fsi_master_mask_set(master, master->regs->imsk, data, 0);
339 fsi_master_mask_set(master, IEMSK, data, 0); 362 fsi_master_mask_set(master, master->regs->iemsk, data, 0);
363}
364
365static u32 fsi_irq_get_status(struct fsi_master *master)
366{
367 return fsi_master_read(master, master->regs->int_st);
368}
369
370static void fsi_irq_clear_all_status(struct fsi_master *master)
371{
372 fsi_master_write(master, master->regs->int_st, 0x0000000);
340} 373}
341 374
375static void fsi_irq_clear_status(struct fsi_priv *fsi)
376{
377 u32 data = 0;
378 struct fsi_master *master = fsi_get_master(fsi);
379
380 data |= fsi_port_ab_io_bit(fsi, 0);
381 data |= fsi_port_ab_io_bit(fsi, 1);
382
383 /* clear interrupt factor */
384 fsi_master_mask_set(master, master->regs->int_st, data, 0);
385}
386
387/************************************************************************
388
389
390 ctrl function
391
392
393************************************************************************/
342static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 394static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
343{ 395{
344 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 396 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
@@ -350,41 +402,61 @@ static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
350 fsi_master_mask_set(master, CLK_RST, val, 0); 402 fsi_master_mask_set(master, CLK_RST, val, 0);
351} 403}
352 404
353static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 405static void fsi_fifo_init(struct fsi_priv *fsi,
406 int is_play,
407 struct snd_soc_dai *dai)
354{ 408{
355 u32 data; 409 struct fsi_master *master = fsi_get_master(fsi);
356 u32 ctrl; 410 u32 ctrl, shift, i;
357 411
358 data = fsi_port_ab_io_bit(fsi, is_play); 412 /* get on-chip RAM capacity */
359 ctrl = is_play ? DOFF_CTL : DIFF_CTL; 413 shift = fsi_master_read(master, FIFO_SZ);
414 shift >>= fsi_is_port_a(fsi) ? AO_SZ_SHIFT : BO_SZ_SHIFT;
415 shift &= OUT_SZ_MASK;
416 fsi->fifo_max = 256 << shift;
417 dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max);
360 418
361 /* set IMSK */ 419 /*
362 fsi_irq_disable(fsi, is_play); 420 * The maximum number of sample data varies depending
421 * on the number of channels selected for the format.
422 *
423 * FIFOs are used in 4-channel units in 3-channel mode
424 * and in 8-channel units in 5- to 7-channel mode
425 * meaning that more FIFOs than the required size of DPRAM
426 * are used.
427 *
428 * ex) if 256 words of DP-RAM is connected
429 * 1 channel: 256 (256 x 1 = 256)
430 * 2 channels: 128 (128 x 2 = 256)
431 * 3 channels: 64 ( 64 x 3 = 192)
432 * 4 channels: 64 ( 64 x 4 = 256)
433 * 5 channels: 32 ( 32 x 5 = 160)
434 * 6 channels: 32 ( 32 x 6 = 192)
435 * 7 channels: 32 ( 32 x 7 = 224)
436 * 8 channels: 32 ( 32 x 8 = 256)
437 */
438 for (i = 1; i < fsi->chan; i <<= 1)
439 fsi->fifo_max >>= 1;
440 dev_dbg(dai->dev, "%d channel %d store\n", fsi->chan, fsi->fifo_max);
441
442 ctrl = is_play ? DOFF_CTL : DIFF_CTL;
363 443
364 /* set interrupt generation factor */ 444 /* set interrupt generation factor */
365 fsi_reg_write(fsi, ctrl, IRQ_HALF); 445 fsi_reg_write(fsi, ctrl, IRQ_HALF);
366 446
367 /* clear FIFO */ 447 /* clear FIFO */
368 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 448 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
369
370 /* clear interrupt factor */
371 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
372} 449}
373 450
374static void fsi_soft_all_reset(struct fsi_master *master) 451static void fsi_soft_all_reset(struct fsi_master *master)
375{ 452{
376 u32 status = fsi_master_read(master, SOFT_RST);
377
378 /* port AB reset */ 453 /* port AB reset */
379 status &= 0x000000ff; 454 fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
380 fsi_master_write(master, SOFT_RST, status);
381 mdelay(10); 455 mdelay(10);
382 456
383 /* soft reset */ 457 /* soft reset */
384 status &= 0x000000f0; 458 fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
385 fsi_master_write(master, SOFT_RST, status); 459 fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
386 status |= 0x00000001;
387 fsi_master_write(master, SOFT_RST, status);
388 mdelay(10); 460 mdelay(10);
389} 461}
390 462
@@ -559,12 +631,11 @@ static int fsi_data_pop(struct fsi_priv *fsi, int startup)
559static irqreturn_t fsi_interrupt(int irq, void *data) 631static irqreturn_t fsi_interrupt(int irq, void *data)
560{ 632{
561 struct fsi_master *master = data; 633 struct fsi_master *master = data;
562 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010; 634 u32 int_st = fsi_irq_get_status(master);
563 u32 int_st = fsi_master_read(master, INT_ST);
564 635
565 /* clear irq status */ 636 /* clear irq status */
566 fsi_master_write(master, SOFT_RST, status); 637 fsi_master_mask_set(master, SOFT_RST, IR, 0);
567 fsi_master_write(master, SOFT_RST, status | 0x00000010); 638 fsi_master_mask_set(master, SOFT_RST, IR, IR);
568 639
569 if (int_st & INT_A_OUT) 640 if (int_st & INT_A_OUT)
570 fsi_data_push(&master->fsia, 0); 641 fsi_data_push(&master->fsia, 0);
@@ -575,7 +646,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
575 if (int_st & INT_B_IN) 646 if (int_st & INT_B_IN)
576 fsi_data_pop(&master->fsib, 0); 647 fsi_data_pop(&master->fsib, 0);
577 648
578 fsi_master_write(master, INT_ST, 0x0000000); 649 fsi_irq_clear_all_status(master);
579 650
580 return IRQ_HANDLED; 651 return IRQ_HANDLED;
581} 652}
@@ -669,29 +740,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
669 dev_err(dai->dev, "unknown format.\n"); 740 dev_err(dai->dev, "unknown format.\n");
670 return -EINVAL; 741 return -EINVAL;
671 } 742 }
672
673 switch (fsi->chan) {
674 case 1:
675 fsi->fifo_max = 256;
676 break;
677 case 2:
678 fsi->fifo_max = 128;
679 break;
680 case 3:
681 case 4:
682 fsi->fifo_max = 64;
683 break;
684 case 5:
685 case 6:
686 case 7:
687 case 8:
688 fsi->fifo_max = 32;
689 break;
690 default:
691 dev_err(dai->dev, "channel size error.\n");
692 return -EINVAL;
693 }
694
695 fsi_reg_write(fsi, reg, data); 743 fsi_reg_write(fsi, reg, data);
696 744
697 /* 745 /*
@@ -700,8 +748,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
700 if (is_master) 748 if (is_master)
701 fsi_clk_ctrl(fsi, 1); 749 fsi_clk_ctrl(fsi, 1);
702 750
703 /* irq setting */ 751 /* irq clear */
704 fsi_irq_init(fsi, is_play); 752 fsi_irq_disable(fsi, is_play);
753 fsi_irq_clear_status(fsi);
754
755 /* fifo init */
756 fsi_fifo_init(fsi, is_play, dai);
705 757
706 return ret; 758 return ret;
707} 759}
@@ -913,6 +965,7 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
913static int fsi_probe(struct platform_device *pdev) 965static int fsi_probe(struct platform_device *pdev)
914{ 966{
915 struct fsi_master *master; 967 struct fsi_master *master;
968 const struct platform_device_id *id_entry;
916 struct resource *res; 969 struct resource *res;
917 unsigned int irq; 970 unsigned int irq;
918 int ret; 971 int ret;
@@ -922,6 +975,12 @@ static int fsi_probe(struct platform_device *pdev)
922 return -ENODEV; 975 return -ENODEV;
923 } 976 }
924 977
978 id_entry = pdev->id_entry;
979 if (!id_entry) {
980 dev_err(&pdev->dev, "unknown fsi device\n");
981 return -ENODEV;
982 }
983
925 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 984 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
926 irq = platform_get_irq(pdev, 0); 985 irq = platform_get_irq(pdev, 0);
927 if (!res || (int)irq <= 0) { 986 if (!res || (int)irq <= 0) {
@@ -950,6 +1009,7 @@ static int fsi_probe(struct platform_device *pdev)
950 master->fsia.master = master; 1009 master->fsia.master = master;
951 master->fsib.base = master->base + 0x40; 1010 master->fsib.base = master->base + 0x40;
952 master->fsib.master = master; 1011 master->fsib.master = master;
1012 master->regs = (struct fsi_regs *)id_entry->driver_data;
953 spin_lock_init(&master->lock); 1013 spin_lock_init(&master->lock);
954 1014
955 pm_runtime_enable(&pdev->dev); 1015 pm_runtime_enable(&pdev->dev);
@@ -962,7 +1022,8 @@ static int fsi_probe(struct platform_device *pdev)
962 1022
963 fsi_soft_all_reset(master); 1023 fsi_soft_all_reset(master);
964 1024
965 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 1025 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
1026 id_entry->name, master);
966 if (ret) { 1027 if (ret) {
967 dev_err(&pdev->dev, "irq request err\n"); 1028 dev_err(&pdev->dev, "irq request err\n");
968 goto exit_iounmap; 1029 goto exit_iounmap;
@@ -1029,6 +1090,23 @@ static struct dev_pm_ops fsi_pm_ops = {
1029 .runtime_resume = fsi_runtime_nop, 1090 .runtime_resume = fsi_runtime_nop,
1030}; 1091};
1031 1092
1093static struct fsi_regs fsi_regs = {
1094 .int_st = INT_ST,
1095 .iemsk = IEMSK,
1096 .imsk = IMSK,
1097};
1098
1099static struct fsi_regs fsi2_regs = {
1100 .int_st = CPU_INT_ST,
1101 .iemsk = CPU_IEMSK,
1102 .imsk = CPU_IMSK,
1103};
1104
1105static struct platform_device_id fsi_id_table[] = {
1106 { "sh_fsi", (kernel_ulong_t)&fsi_regs },
1107 { "sh_fsi2", (kernel_ulong_t)&fsi2_regs },
1108};
1109
1032static struct platform_driver fsi_driver = { 1110static struct platform_driver fsi_driver = {
1033 .driver = { 1111 .driver = {
1034 .name = "sh_fsi", 1112 .name = "sh_fsi",
@@ -1036,6 +1114,7 @@ static struct platform_driver fsi_driver = {
1036 }, 1114 },
1037 .probe = fsi_probe, 1115 .probe = fsi_probe,
1038 .remove = fsi_remove, 1116 .remove = fsi_remove,
1117 .id_table = fsi_id_table,
1039}; 1118};
1040 1119
1041static int __init fsi_mobile_init(void) 1120static int __init fsi_mobile_init(void)
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 5869dc3be781..472af38188c1 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -44,6 +44,8 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
44 return 0; 44 return 0;
45 } 45 }
46 46
47 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
48
47 ret = codec->hw_write(codec->control_data, data, 2); 49 ret = codec->hw_write(codec->control_data, data, 2);
48 if (ret == 2) 50 if (ret == 2)
49 return 0; 51 return 0;
@@ -112,6 +114,8 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
112 return 0; 114 return 0;
113 } 115 }
114 116
117 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
118
115 ret = codec->hw_write(codec->control_data, data, 2); 119 ret = codec->hw_write(codec->control_data, data, 2);
116 if (ret == 2) 120 if (ret == 2)
117 return 0; 121 return 0;
@@ -159,7 +163,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
159 163
160 BUG_ON(codec->volatile_register); 164 BUG_ON(codec->volatile_register);
161 165
162 data[0] = reg & 0xff; 166 reg &= 0xff;
167 data[0] = reg;
163 data[1] = value & 0xff; 168 data[1] = value & 0xff;
164 169
165 if (reg < codec->reg_cache_size) 170 if (reg < codec->reg_cache_size)
@@ -170,6 +175,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
170 return 0; 175 return 0;
171 } 176 }
172 177
178 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
179
173 if (codec->hw_write(codec->control_data, data, 2) == 2) 180 if (codec->hw_write(codec->control_data, data, 2) == 2)
174 return 0; 181 return 0;
175 else 182 else
@@ -180,6 +187,7 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
180 unsigned int reg) 187 unsigned int reg)
181{ 188{
182 u8 *cache = codec->reg_cache; 189 u8 *cache = codec->reg_cache;
190 reg &= 0xff;
183 if (reg >= codec->reg_cache_size) 191 if (reg >= codec->reg_cache_size)
184 return -1; 192 return -1;
185 return cache[reg]; 193 return cache[reg];
@@ -203,6 +211,8 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
203 return 0; 211 return 0;
204 } 212 }
205 213
214 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
215
206 if (codec->hw_write(codec->control_data, data, 3) == 3) 216 if (codec->hw_write(codec->control_data, data, 3) == 3)
207 return 0; 217 return 0;
208 else 218 else
@@ -226,6 +236,40 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
226} 236}
227 237
228#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 238#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
239static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec,
240 unsigned int r)
241{
242 struct i2c_msg xfer[2];
243 u8 reg = r;
244 u8 data;
245 int ret;
246 struct i2c_client *client = codec->control_data;
247
248 /* Write register */
249 xfer[0].addr = client->addr;
250 xfer[0].flags = 0;
251 xfer[0].len = 1;
252 xfer[0].buf = &reg;
253
254 /* Read data */
255 xfer[1].addr = client->addr;
256 xfer[1].flags = I2C_M_RD;
257 xfer[1].len = 1;
258 xfer[1].buf = &data;
259
260 ret = i2c_transfer(client->adapter, xfer, 2);
261 if (ret != 2) {
262 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
263 return 0;
264 }
265
266 return data;
267}
268#else
269#define snd_soc_8_8_read_i2c NULL
270#endif
271
272#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
229static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, 273static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
230 unsigned int r) 274 unsigned int r)
231{ 275{
@@ -326,6 +370,8 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
326 return 0; 370 return 0;
327 } 371 }
328 372
373 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
374
329 ret = codec->hw_write(codec->control_data, data, 3); 375 ret = codec->hw_write(codec->control_data, data, 3);
330 if (ret == 3) 376 if (ret == 3)
331 return 0; 377 return 0;
@@ -366,6 +412,86 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data,
366#define snd_soc_16_8_spi_write NULL 412#define snd_soc_16_8_spi_write NULL
367#endif 413#endif
368 414
415#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
416static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
417 unsigned int r)
418{
419 struct i2c_msg xfer[2];
420 u16 reg = cpu_to_be16(r);
421 u16 data;
422 int ret;
423 struct i2c_client *client = codec->control_data;
424
425 /* Write register */
426 xfer[0].addr = client->addr;
427 xfer[0].flags = 0;
428 xfer[0].len = 2;
429 xfer[0].buf = (u8 *)&reg;
430
431 /* Read data */
432 xfer[1].addr = client->addr;
433 xfer[1].flags = I2C_M_RD;
434 xfer[1].len = 2;
435 xfer[1].buf = (u8 *)&data;
436
437 ret = i2c_transfer(client->adapter, xfer, 2);
438 if (ret != 2) {
439 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
440 return 0;
441 }
442
443 return be16_to_cpu(data);
444}
445#else
446#define snd_soc_16_16_read_i2c NULL
447#endif
448
449static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
450 unsigned int reg)
451{
452 u16 *cache = codec->reg_cache;
453
454 if (reg >= codec->reg_cache_size ||
455 snd_soc_codec_volatile_register(codec, reg)) {
456 if (codec->cache_only)
457 return -EINVAL;
458
459 return codec->hw_read(codec, reg);
460 }
461
462 return cache[reg];
463}
464
465static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
466 unsigned int value)
467{
468 u16 *cache = codec->reg_cache;
469 u8 data[4];
470 int ret;
471
472 data[0] = (reg >> 8) & 0xff;
473 data[1] = reg & 0xff;
474 data[2] = (value >> 8) & 0xff;
475 data[3] = value & 0xff;
476
477 if (reg < codec->reg_cache_size)
478 cache[reg] = value;
479
480 if (codec->cache_only) {
481 codec->cache_sync = 1;
482 return 0;
483 }
484
485 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
486
487 ret = codec->hw_write(codec->control_data, data, 4);
488 if (ret == 4)
489 return 0;
490 if (ret < 0)
491 return ret;
492 else
493 return -EIO;
494}
369 495
370static struct { 496static struct {
371 int addr_bits; 497 int addr_bits;
@@ -388,6 +514,7 @@ static struct {
388 { 514 {
389 .addr_bits = 8, .data_bits = 8, 515 .addr_bits = 8, .data_bits = 8,
390 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read, 516 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
517 .i2c_read = snd_soc_8_8_read_i2c,
391 }, 518 },
392 { 519 {
393 .addr_bits = 8, .data_bits = 16, 520 .addr_bits = 8, .data_bits = 16,
@@ -400,6 +527,11 @@ static struct {
400 .i2c_read = snd_soc_16_8_read_i2c, 527 .i2c_read = snd_soc_16_8_read_i2c,
401 .spi_write = snd_soc_16_8_spi_write, 528 .spi_write = snd_soc_16_8_spi_write,
402 }, 529 },
530 {
531 .addr_bits = 16, .data_bits = 16,
532 .write = snd_soc_16_16_write, .read = snd_soc_16_16_read,
533 .i2c_read = snd_soc_16_16_read_i2c,
534 },
403}; 535};
404 536
405/** 537/**
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ad7f9528d751..998569d60330 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -316,7 +316,7 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
316 316
317 if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates || 317 if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates ||
318 machine->symmetric_rates) { 318 machine->symmetric_rates) {
319 dev_dbg(card->dev, "Symmetry forces %dHz rate\n", 319 dev_dbg(card->dev, "Symmetry forces %dHz rate\n",
320 machine->rate); 320 machine->rate);
321 321
322 ret = snd_pcm_hw_constraint_minmax(substream->runtime, 322 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
@@ -405,6 +405,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
405 codec_dai->playback.formats & cpu_dai->playback.formats; 405 codec_dai->playback.formats & cpu_dai->playback.formats;
406 runtime->hw.rates = 406 runtime->hw.rates =
407 codec_dai->playback.rates & cpu_dai->playback.rates; 407 codec_dai->playback.rates & cpu_dai->playback.rates;
408 if (codec_dai->playback.rates
409 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
410 runtime->hw.rates |= cpu_dai->playback.rates;
411 if (cpu_dai->playback.rates
412 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
413 runtime->hw.rates |= codec_dai->playback.rates;
408 } else { 414 } else {
409 runtime->hw.rate_min = 415 runtime->hw.rate_min =
410 max(codec_dai->capture.rate_min, 416 max(codec_dai->capture.rate_min,
@@ -422,6 +428,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
422 codec_dai->capture.formats & cpu_dai->capture.formats; 428 codec_dai->capture.formats & cpu_dai->capture.formats;
423 runtime->hw.rates = 429 runtime->hw.rates =
424 codec_dai->capture.rates & cpu_dai->capture.rates; 430 codec_dai->capture.rates & cpu_dai->capture.rates;
431 if (codec_dai->capture.rates
432 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
433 runtime->hw.rates |= cpu_dai->capture.rates;
434 if (cpu_dai->capture.rates
435 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
436 runtime->hw.rates |= codec_dai->capture.rates;
425 } 437 }
426 438
427 snd_pcm_limit_hw_rates(runtime); 439 snd_pcm_limit_hw_rates(runtime);
@@ -455,12 +467,15 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
455 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 467 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
456 runtime->hw.rate_max); 468 runtime->hw.rate_max);
457 469
458 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 470 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
459 cpu_dai->playback.active = codec_dai->playback.active = 1; 471 cpu_dai->playback.active++;
460 else 472 codec_dai->playback.active++;
461 cpu_dai->capture.active = codec_dai->capture.active = 1; 473 } else {
462 cpu_dai->active = codec_dai->active = 1; 474 cpu_dai->capture.active++;
463 cpu_dai->runtime = runtime; 475 codec_dai->capture.active++;
476 }
477 cpu_dai->active++;
478 codec_dai->active++;
464 card->codec->active++; 479 card->codec->active++;
465 mutex_unlock(&pcm_mutex); 480 mutex_unlock(&pcm_mutex);
466 return 0; 481 return 0;
@@ -536,15 +551,16 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
536 551
537 mutex_lock(&pcm_mutex); 552 mutex_lock(&pcm_mutex);
538 553
539 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 554 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
540 cpu_dai->playback.active = codec_dai->playback.active = 0; 555 cpu_dai->playback.active--;
541 else 556 codec_dai->playback.active--;
542 cpu_dai->capture.active = codec_dai->capture.active = 0; 557 } else {
543 558 cpu_dai->capture.active--;
544 if (codec_dai->playback.active == 0 && 559 codec_dai->capture.active--;
545 codec_dai->capture.active == 0) {
546 cpu_dai->active = codec_dai->active = 0;
547 } 560 }
561
562 cpu_dai->active--;
563 codec_dai->active--;
548 codec->active--; 564 codec->active--;
549 565
550 /* Muting the DAC suppresses artifacts caused during digital 566 /* Muting the DAC suppresses artifacts caused during digital
@@ -564,7 +580,6 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
564 580
565 if (platform->pcm_ops->close) 581 if (platform->pcm_ops->close)
566 platform->pcm_ops->close(substream); 582 platform->pcm_ops->close(substream);
567 cpu_dai->runtime = NULL;
568 583
569 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 584 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
570 /* start delayed pop wq here for playback streams */ 585 /* start delayed pop wq here for playback streams */
@@ -802,6 +817,41 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
802 return 0; 817 return 0;
803} 818}
804 819
820/*
821 * soc level wrapper for pointer callback
822 * If cpu_dai, codec_dai, platform driver has the delay callback, than
823 * the runtime->delay will be updated accordingly.
824 */
825static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
826{
827 struct snd_soc_pcm_runtime *rtd = substream->private_data;
828 struct snd_soc_device *socdev = rtd->socdev;
829 struct snd_soc_card *card = socdev->card;
830 struct snd_soc_platform *platform = card->platform;
831 struct snd_soc_dai_link *machine = rtd->dai;
832 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
833 struct snd_soc_dai *codec_dai = machine->codec_dai;
834 struct snd_pcm_runtime *runtime = substream->runtime;
835 snd_pcm_uframes_t offset = 0;
836 snd_pcm_sframes_t delay = 0;
837
838 if (platform->pcm_ops->pointer)
839 offset = platform->pcm_ops->pointer(substream);
840
841 if (cpu_dai->ops->delay)
842 delay += cpu_dai->ops->delay(substream, cpu_dai);
843
844 if (codec_dai->ops->delay)
845 delay += codec_dai->ops->delay(substream, codec_dai);
846
847 if (platform->delay)
848 delay += platform->delay(substream, codec_dai);
849
850 runtime->delay = delay;
851
852 return offset;
853}
854
805/* ASoC PCM operations */ 855/* ASoC PCM operations */
806static struct snd_pcm_ops soc_pcm_ops = { 856static struct snd_pcm_ops soc_pcm_ops = {
807 .open = soc_pcm_open, 857 .open = soc_pcm_open,
@@ -810,6 +860,7 @@ static struct snd_pcm_ops soc_pcm_ops = {
810 .hw_free = soc_pcm_hw_free, 860 .hw_free = soc_pcm_hw_free,
811 .prepare = soc_pcm_prepare, 861 .prepare = soc_pcm_prepare,
812 .trigger = soc_pcm_trigger, 862 .trigger = soc_pcm_trigger,
863 .pointer = soc_pcm_pointer,
813}; 864};
814 865
815#ifdef CONFIG_PM 866#ifdef CONFIG_PM
@@ -843,23 +894,35 @@ static int soc_suspend(struct device *dev)
843 /* mute any active DAC's */ 894 /* mute any active DAC's */
844 for (i = 0; i < card->num_links; i++) { 895 for (i = 0; i < card->num_links; i++) {
845 struct snd_soc_dai *dai = card->dai_link[i].codec_dai; 896 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
897
898 if (card->dai_link[i].ignore_suspend)
899 continue;
900
846 if (dai->ops->digital_mute && dai->playback.active) 901 if (dai->ops->digital_mute && dai->playback.active)
847 dai->ops->digital_mute(dai, 1); 902 dai->ops->digital_mute(dai, 1);
848 } 903 }
849 904
850 /* suspend all pcms */ 905 /* suspend all pcms */
851 for (i = 0; i < card->num_links; i++) 906 for (i = 0; i < card->num_links; i++) {
907 if (card->dai_link[i].ignore_suspend)
908 continue;
909
852 snd_pcm_suspend_all(card->dai_link[i].pcm); 910 snd_pcm_suspend_all(card->dai_link[i].pcm);
911 }
853 912
854 if (card->suspend_pre) 913 if (card->suspend_pre)
855 card->suspend_pre(pdev, PMSG_SUSPEND); 914 card->suspend_pre(pdev, PMSG_SUSPEND);
856 915
857 for (i = 0; i < card->num_links; i++) { 916 for (i = 0; i < card->num_links; i++) {
858 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 917 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
918
919 if (card->dai_link[i].ignore_suspend)
920 continue;
921
859 if (cpu_dai->suspend && !cpu_dai->ac97_control) 922 if (cpu_dai->suspend && !cpu_dai->ac97_control)
860 cpu_dai->suspend(cpu_dai); 923 cpu_dai->suspend(cpu_dai);
861 if (platform->suspend) 924 if (platform->suspend)
862 platform->suspend(cpu_dai); 925 platform->suspend(&card->dai_link[i]);
863 } 926 }
864 927
865 /* close any waiting streams and save state */ 928 /* close any waiting streams and save state */
@@ -868,6 +931,10 @@ static int soc_suspend(struct device *dev)
868 931
869 for (i = 0; i < codec->num_dai; i++) { 932 for (i = 0; i < codec->num_dai; i++) {
870 char *stream = codec->dai[i].playback.stream_name; 933 char *stream = codec->dai[i].playback.stream_name;
934
935 if (card->dai_link[i].ignore_suspend)
936 continue;
937
871 if (stream != NULL) 938 if (stream != NULL)
872 snd_soc_dapm_stream_event(codec, stream, 939 snd_soc_dapm_stream_event(codec, stream,
873 SND_SOC_DAPM_STREAM_SUSPEND); 940 SND_SOC_DAPM_STREAM_SUSPEND);
@@ -877,11 +944,26 @@ static int soc_suspend(struct device *dev)
877 SND_SOC_DAPM_STREAM_SUSPEND); 944 SND_SOC_DAPM_STREAM_SUSPEND);
878 } 945 }
879 946
880 if (codec_dev->suspend) 947 /* If there are paths active then the CODEC will be held with
881 codec_dev->suspend(pdev, PMSG_SUSPEND); 948 * bias _ON and should not be suspended. */
949 if (codec_dev->suspend) {
950 switch (codec->bias_level) {
951 case SND_SOC_BIAS_STANDBY:
952 case SND_SOC_BIAS_OFF:
953 codec_dev->suspend(pdev, PMSG_SUSPEND);
954 break;
955 default:
956 dev_dbg(socdev->dev, "CODEC is on over suspend\n");
957 break;
958 }
959 }
882 960
883 for (i = 0; i < card->num_links; i++) { 961 for (i = 0; i < card->num_links; i++) {
884 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 962 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
963
964 if (card->dai_link[i].ignore_suspend)
965 continue;
966
885 if (cpu_dai->suspend && cpu_dai->ac97_control) 967 if (cpu_dai->suspend && cpu_dai->ac97_control)
886 cpu_dai->suspend(cpu_dai); 968 cpu_dai->suspend(cpu_dai);
887 } 969 }
@@ -913,20 +995,44 @@ static void soc_resume_deferred(struct work_struct *work)
913 995
914 dev_dbg(socdev->dev, "starting resume work\n"); 996 dev_dbg(socdev->dev, "starting resume work\n");
915 997
998 /* Bring us up into D2 so that DAPM starts enabling things */
999 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D2);
1000
916 if (card->resume_pre) 1001 if (card->resume_pre)
917 card->resume_pre(pdev); 1002 card->resume_pre(pdev);
918 1003
919 for (i = 0; i < card->num_links; i++) { 1004 for (i = 0; i < card->num_links; i++) {
920 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1005 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
1006
1007 if (card->dai_link[i].ignore_suspend)
1008 continue;
1009
921 if (cpu_dai->resume && cpu_dai->ac97_control) 1010 if (cpu_dai->resume && cpu_dai->ac97_control)
922 cpu_dai->resume(cpu_dai); 1011 cpu_dai->resume(cpu_dai);
923 } 1012 }
924 1013
925 if (codec_dev->resume) 1014 /* If the CODEC was idle over suspend then it will have been
926 codec_dev->resume(pdev); 1015 * left with bias OFF or STANDBY and suspended so we must now
1016 * resume. Otherwise the suspend was suppressed.
1017 */
1018 if (codec_dev->resume) {
1019 switch (codec->bias_level) {
1020 case SND_SOC_BIAS_STANDBY:
1021 case SND_SOC_BIAS_OFF:
1022 codec_dev->resume(pdev);
1023 break;
1024 default:
1025 dev_dbg(socdev->dev, "CODEC was on over suspend\n");
1026 break;
1027 }
1028 }
927 1029
928 for (i = 0; i < codec->num_dai; i++) { 1030 for (i = 0; i < codec->num_dai; i++) {
929 char *stream = codec->dai[i].playback.stream_name; 1031 char *stream = codec->dai[i].playback.stream_name;
1032
1033 if (card->dai_link[i].ignore_suspend)
1034 continue;
1035
930 if (stream != NULL) 1036 if (stream != NULL)
931 snd_soc_dapm_stream_event(codec, stream, 1037 snd_soc_dapm_stream_event(codec, stream,
932 SND_SOC_DAPM_STREAM_RESUME); 1038 SND_SOC_DAPM_STREAM_RESUME);
@@ -939,16 +1045,24 @@ static void soc_resume_deferred(struct work_struct *work)
939 /* unmute any active DACs */ 1045 /* unmute any active DACs */
940 for (i = 0; i < card->num_links; i++) { 1046 for (i = 0; i < card->num_links; i++) {
941 struct snd_soc_dai *dai = card->dai_link[i].codec_dai; 1047 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
1048
1049 if (card->dai_link[i].ignore_suspend)
1050 continue;
1051
942 if (dai->ops->digital_mute && dai->playback.active) 1052 if (dai->ops->digital_mute && dai->playback.active)
943 dai->ops->digital_mute(dai, 0); 1053 dai->ops->digital_mute(dai, 0);
944 } 1054 }
945 1055
946 for (i = 0; i < card->num_links; i++) { 1056 for (i = 0; i < card->num_links; i++) {
947 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1057 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
1058
1059 if (card->dai_link[i].ignore_suspend)
1060 continue;
1061
948 if (cpu_dai->resume && !cpu_dai->ac97_control) 1062 if (cpu_dai->resume && !cpu_dai->ac97_control)
949 cpu_dai->resume(cpu_dai); 1063 cpu_dai->resume(cpu_dai);
950 if (platform->resume) 1064 if (platform->resume)
951 platform->resume(cpu_dai); 1065 platform->resume(&card->dai_link[i]);
952 } 1066 }
953 1067
954 if (card->resume_post) 1068 if (card->resume_post)
@@ -1233,26 +1347,25 @@ static int soc_remove(struct platform_device *pdev)
1233 struct snd_soc_platform *platform = card->platform; 1347 struct snd_soc_platform *platform = card->platform;
1234 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 1348 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
1235 1349
1236 if (!card->instantiated) 1350 if (card->instantiated) {
1237 return 0; 1351 run_delayed_work(&card->delayed_work);
1238 1352
1239 run_delayed_work(&card->delayed_work); 1353 if (platform->remove)
1354 platform->remove(pdev);
1240 1355
1241 if (platform->remove) 1356 if (codec_dev->remove)
1242 platform->remove(pdev); 1357 codec_dev->remove(pdev);
1243 1358
1244 if (codec_dev->remove) 1359 for (i = 0; i < card->num_links; i++) {
1245 codec_dev->remove(pdev); 1360 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
1361 if (cpu_dai->remove)
1362 cpu_dai->remove(pdev, cpu_dai);
1363 }
1246 1364
1247 for (i = 0; i < card->num_links; i++) { 1365 if (card->remove)
1248 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 1366 card->remove(pdev);
1249 if (cpu_dai->remove)
1250 cpu_dai->remove(pdev, cpu_dai);
1251 } 1367 }
1252 1368
1253 if (card->remove)
1254 card->remove(pdev);
1255
1256 snd_soc_unregister_card(card); 1369 snd_soc_unregister_card(card);
1257 1370
1258 return 0; 1371 return 0;
@@ -1336,7 +1449,6 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1336 dai_link->pcm = pcm; 1449 dai_link->pcm = pcm;
1337 pcm->private_data = rtd; 1450 pcm->private_data = rtd;
1338 soc_pcm_ops.mmap = platform->pcm_ops->mmap; 1451 soc_pcm_ops.mmap = platform->pcm_ops->mmap;
1339 soc_pcm_ops.pointer = platform->pcm_ops->pointer;
1340 soc_pcm_ops.ioctl = platform->pcm_ops->ioctl; 1452 soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
1341 soc_pcm_ops.copy = platform->pcm_ops->copy; 1453 soc_pcm_ops.copy = platform->pcm_ops->copy;
1342 soc_pcm_ops.silence = platform->pcm_ops->silence; 1454 soc_pcm_ops.silence = platform->pcm_ops->silence;
@@ -1906,18 +2018,22 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
1906{ 2018{
1907 struct soc_mixer_control *mc = 2019 struct soc_mixer_control *mc =
1908 (struct soc_mixer_control *)kcontrol->private_value; 2020 (struct soc_mixer_control *)kcontrol->private_value;
1909 int max = mc->max; 2021 int platform_max;
1910 unsigned int shift = mc->shift; 2022 unsigned int shift = mc->shift;
1911 unsigned int rshift = mc->rshift; 2023 unsigned int rshift = mc->rshift;
1912 2024
1913 if (max == 1 && !strstr(kcontrol->id.name, " Volume")) 2025 if (!mc->platform_max)
2026 mc->platform_max = mc->max;
2027 platform_max = mc->platform_max;
2028
2029 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
1914 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2030 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1915 else 2031 else
1916 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2032 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1917 2033
1918 uinfo->count = shift == rshift ? 1 : 2; 2034 uinfo->count = shift == rshift ? 1 : 2;
1919 uinfo->value.integer.min = 0; 2035 uinfo->value.integer.min = 0;
1920 uinfo->value.integer.max = max; 2036 uinfo->value.integer.max = platform_max;
1921 return 0; 2037 return 0;
1922} 2038}
1923EXPORT_SYMBOL_GPL(snd_soc_info_volsw); 2039EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
@@ -2015,16 +2131,20 @@ int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
2015{ 2131{
2016 struct soc_mixer_control *mc = 2132 struct soc_mixer_control *mc =
2017 (struct soc_mixer_control *)kcontrol->private_value; 2133 (struct soc_mixer_control *)kcontrol->private_value;
2018 int max = mc->max; 2134 int platform_max;
2019 2135
2020 if (max == 1 && !strstr(kcontrol->id.name, " Volume")) 2136 if (!mc->platform_max)
2137 mc->platform_max = mc->max;
2138 platform_max = mc->platform_max;
2139
2140 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume"))
2021 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 2141 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2022 else 2142 else
2023 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2143 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2024 2144
2025 uinfo->count = 2; 2145 uinfo->count = 2;
2026 uinfo->value.integer.min = 0; 2146 uinfo->value.integer.min = 0;
2027 uinfo->value.integer.max = max; 2147 uinfo->value.integer.max = platform_max;
2028 return 0; 2148 return 0;
2029} 2149}
2030EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); 2150EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
@@ -2125,13 +2245,17 @@ int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
2125{ 2245{
2126 struct soc_mixer_control *mc = 2246 struct soc_mixer_control *mc =
2127 (struct soc_mixer_control *)kcontrol->private_value; 2247 (struct soc_mixer_control *)kcontrol->private_value;
2128 int max = mc->max; 2248 int platform_max;
2129 int min = mc->min; 2249 int min = mc->min;
2130 2250
2251 if (!mc->platform_max)
2252 mc->platform_max = mc->max;
2253 platform_max = mc->platform_max;
2254
2131 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 2255 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2132 uinfo->count = 2; 2256 uinfo->count = 2;
2133 uinfo->value.integer.min = 0; 2257 uinfo->value.integer.min = 0;
2134 uinfo->value.integer.max = max-min; 2258 uinfo->value.integer.max = platform_max - min;
2135 return 0; 2259 return 0;
2136} 2260}
2137EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8); 2261EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
@@ -2190,6 +2314,45 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2190EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); 2314EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2191 2315
2192/** 2316/**
2317 * snd_soc_limit_volume - Set new limit to an existing volume control.
2318 *
2319 * @codec: where to look for the control
2320 * @name: Name of the control
2321 * @max: new maximum limit
2322 *
2323 * Return 0 for success, else error.
2324 */
2325int snd_soc_limit_volume(struct snd_soc_codec *codec,
2326 const char *name, int max)
2327{
2328 struct snd_card *card = codec->card;
2329 struct snd_kcontrol *kctl;
2330 struct soc_mixer_control *mc;
2331 int found = 0;
2332 int ret = -EINVAL;
2333
2334 /* Sanity check for name and max */
2335 if (unlikely(!name || max <= 0))
2336 return -EINVAL;
2337
2338 list_for_each_entry(kctl, &card->controls, list) {
2339 if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) {
2340 found = 1;
2341 break;
2342 }
2343 }
2344 if (found) {
2345 mc = (struct soc_mixer_control *)kctl->private_value;
2346 if (max <= mc->max) {
2347 mc->platform_max = max;
2348 ret = 0;
2349 }
2350 }
2351 return ret;
2352}
2353EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
2354
2355/**
2193 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 2356 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2194 * @dai: DAI 2357 * @dai: DAI
2195 * @clk_id: DAI specific clock ID 2358 * @clk_id: DAI specific clock ID
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7c28f401f436..03cb7c05ebec 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -98,7 +98,6 @@ static void pop_dbg(u32 pop_time, const char *fmt, ...)
98 98
99 if (pop_time) { 99 if (pop_time) {
100 vprintk(fmt, args); 100 vprintk(fmt, args);
101 pop_wait(pop_time);
102 } 101 }
103 102
104 va_end(args); 103 va_end(args);
@@ -315,62 +314,14 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
315 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n", 314 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
316 widget->name, widget->power ? "on" : "off", 315 widget->name, widget->power ? "on" : "off",
317 codec->pop_time); 316 codec->pop_time);
318 snd_soc_write(codec, widget->reg, new);
319 pop_wait(codec->pop_time); 317 pop_wait(codec->pop_time);
318 snd_soc_write(codec, widget->reg, new);
320 } 319 }
321 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 320 pr_debug("reg %x old %x new %x change %d\n", widget->reg,
322 old, new, change); 321 old, new, change);
323 return change; 322 return change;
324} 323}
325 324
326/* ramps the volume up or down to minimise pops before or after a
327 * DAPM power event */
328static int dapm_set_pga(struct snd_soc_dapm_widget *widget, int power)
329{
330 const struct snd_kcontrol_new *k = widget->kcontrols;
331
332 if (widget->muted && !power)
333 return 0;
334 if (!widget->muted && power)
335 return 0;
336
337 if (widget->num_kcontrols && k) {
338 struct soc_mixer_control *mc =
339 (struct soc_mixer_control *)k->private_value;
340 unsigned int reg = mc->reg;
341 unsigned int shift = mc->shift;
342 int max = mc->max;
343 unsigned int mask = (1 << fls(max)) - 1;
344 unsigned int invert = mc->invert;
345
346 if (power) {
347 int i;
348 /* power up has happended, increase volume to last level */
349 if (invert) {
350 for (i = max; i > widget->saved_value; i--)
351 snd_soc_update_bits(widget->codec, reg, mask, i);
352 } else {
353 for (i = 0; i < widget->saved_value; i++)
354 snd_soc_update_bits(widget->codec, reg, mask, i);
355 }
356 widget->muted = 0;
357 } else {
358 /* power down is about to occur, decrease volume to mute */
359 int val = snd_soc_read(widget->codec, reg);
360 int i = widget->saved_value = (val >> shift) & mask;
361 if (invert) {
362 for (; i < mask; i++)
363 snd_soc_update_bits(widget->codec, reg, mask, i);
364 } else {
365 for (; i > 0; i--)
366 snd_soc_update_bits(widget->codec, reg, mask, i);
367 }
368 widget->muted = 1;
369 }
370 }
371 return 0;
372}
373
374/* create new dapm mixer control */ 325/* create new dapm mixer control */
375static int dapm_new_mixer(struct snd_soc_codec *codec, 326static int dapm_new_mixer(struct snd_soc_codec *codec,
376 struct snd_soc_dapm_widget *w) 327 struct snd_soc_dapm_widget *w)
@@ -465,20 +416,10 @@ err:
465static int dapm_new_pga(struct snd_soc_codec *codec, 416static int dapm_new_pga(struct snd_soc_codec *codec,
466 struct snd_soc_dapm_widget *w) 417 struct snd_soc_dapm_widget *w)
467{ 418{
468 struct snd_kcontrol *kcontrol; 419 if (w->num_kcontrols)
469 int ret = 0; 420 pr_err("asoc: PGA controls not supported: '%s'\n", w->name);
470
471 if (!w->num_kcontrols)
472 return -EINVAL;
473 421
474 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); 422 return 0;
475 ret = snd_ctl_add(codec->card, kcontrol);
476 if (ret < 0) {
477 printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name);
478 return ret;
479 }
480
481 return ret;
482} 423}
483 424
484/* reset 'walked' bit for each dapm path */ 425/* reset 'walked' bit for each dapm path */
@@ -490,6 +431,25 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec)
490 p->walked = 0; 431 p->walked = 0;
491} 432}
492 433
434/* We implement power down on suspend by checking the power state of
435 * the ALSA card - when we are suspending the ALSA state for the card
436 * is set to D3.
437 */
438static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
439{
440 struct snd_soc_codec *codec = widget->codec;
441
442 switch (snd_power_get_state(codec->card)) {
443 case SNDRV_CTL_POWER_D3hot:
444 case SNDRV_CTL_POWER_D3cold:
445 if (widget->ignore_suspend)
446 pr_debug("%s ignoring suspend\n", widget->name);
447 return widget->ignore_suspend;
448 default:
449 return 1;
450 }
451}
452
493/* 453/*
494 * Recursively check for a completed path to an active or physically connected 454 * Recursively check for a completed path to an active or physically connected
495 * output widget. Returns number of complete paths. 455 * output widget. Returns number of complete paths.
@@ -506,7 +466,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
506 case snd_soc_dapm_adc: 466 case snd_soc_dapm_adc:
507 case snd_soc_dapm_aif_out: 467 case snd_soc_dapm_aif_out:
508 if (widget->active) 468 if (widget->active)
509 return 1; 469 return snd_soc_dapm_suspend_check(widget);
510 default: 470 default:
511 break; 471 break;
512 } 472 }
@@ -514,12 +474,12 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
514 if (widget->connected) { 474 if (widget->connected) {
515 /* connected pin ? */ 475 /* connected pin ? */
516 if (widget->id == snd_soc_dapm_output && !widget->ext) 476 if (widget->id == snd_soc_dapm_output && !widget->ext)
517 return 1; 477 return snd_soc_dapm_suspend_check(widget);
518 478
519 /* connected jack or spk ? */ 479 /* connected jack or spk ? */
520 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || 480 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk ||
521 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) 481 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources)))
522 return 1; 482 return snd_soc_dapm_suspend_check(widget);
523 } 483 }
524 484
525 list_for_each_entry(path, &widget->sinks, list_source) { 485 list_for_each_entry(path, &widget->sinks, list_source) {
@@ -552,7 +512,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
552 case snd_soc_dapm_dac: 512 case snd_soc_dapm_dac:
553 case snd_soc_dapm_aif_in: 513 case snd_soc_dapm_aif_in:
554 if (widget->active) 514 if (widget->active)
555 return 1; 515 return snd_soc_dapm_suspend_check(widget);
556 default: 516 default:
557 break; 517 break;
558 } 518 }
@@ -560,16 +520,16 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
560 if (widget->connected) { 520 if (widget->connected) {
561 /* connected pin ? */ 521 /* connected pin ? */
562 if (widget->id == snd_soc_dapm_input && !widget->ext) 522 if (widget->id == snd_soc_dapm_input && !widget->ext)
563 return 1; 523 return snd_soc_dapm_suspend_check(widget);
564 524
565 /* connected VMID/Bias for lower pops */ 525 /* connected VMID/Bias for lower pops */
566 if (widget->id == snd_soc_dapm_vmid) 526 if (widget->id == snd_soc_dapm_vmid)
567 return 1; 527 return snd_soc_dapm_suspend_check(widget);
568 528
569 /* connected jack ? */ 529 /* connected jack ? */
570 if (widget->id == snd_soc_dapm_mic || 530 if (widget->id == snd_soc_dapm_mic ||
571 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) 531 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks)))
572 return 1; 532 return snd_soc_dapm_suspend_check(widget);
573 } 533 }
574 534
575 list_for_each_entry(path, &widget->sources, list_sink) { 535 list_for_each_entry(path, &widget->sources, list_sink) {
@@ -634,16 +594,8 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
634 return ret; 594 return ret;
635 } 595 }
636 596
637 /* Lower PGA volume to reduce pops */
638 if (w->id == snd_soc_dapm_pga && !w->power)
639 dapm_set_pga(w, w->power);
640
641 dapm_update_bits(w); 597 dapm_update_bits(w);
642 598
643 /* Raise PGA volume to reduce pops */
644 if (w->id == snd_soc_dapm_pga && w->power)
645 dapm_set_pga(w, w->power);
646
647 /* power up post event */ 599 /* power up post event */
648 if (w->power && w->event && 600 if (w->power && w->event &&
649 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 601 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
@@ -810,10 +762,6 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
810 pr_err("%s: pre event failed: %d\n", 762 pr_err("%s: pre event failed: %d\n",
811 w->name, ret); 763 w->name, ret);
812 } 764 }
813
814 /* Lower PGA volume to reduce pops */
815 if (w->id == snd_soc_dapm_pga && !w->power)
816 dapm_set_pga(w, w->power);
817 } 765 }
818 766
819 if (reg >= 0) { 767 if (reg >= 0) {
@@ -825,10 +773,6 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
825 } 773 }
826 774
827 list_for_each_entry(w, pending, power_list) { 775 list_for_each_entry(w, pending, power_list) {
828 /* Raise PGA volume to reduce pops */
829 if (w->id == snd_soc_dapm_pga && w->power)
830 dapm_set_pga(w, w->power);
831
832 /* power up post event */ 776 /* power up post event */
833 if (w->power && w->event && 777 if (w->power && w->event &&
834 (w->event_flags & SND_SOC_DAPM_POST_PMU)) { 778 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
@@ -973,19 +917,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
973 if (!w->power_check) 917 if (!w->power_check)
974 continue; 918 continue;
975 919
976 /* If we're suspending then pull down all the 920 if (!w->force)
977 * power. */
978 switch (event) {
979 case SND_SOC_DAPM_STREAM_SUSPEND:
980 power = 0;
981 break;
982
983 default:
984 power = w->power_check(w); 921 power = w->power_check(w);
985 if (power) 922 else
986 sys_power = 1; 923 power = 1;
987 break; 924 if (power)
988 } 925 sys_power = 1;
989 926
990 if (w->power == power) 927 if (w->power == power)
991 continue; 928 continue;
@@ -1076,6 +1013,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1076 1013
1077 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n", 1014 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n",
1078 codec->pop_time); 1015 codec->pop_time);
1016 pop_wait(codec->pop_time);
1079 1017
1080 return 0; 1018 return 0;
1081} 1019}
@@ -1338,6 +1276,9 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
1338 if (!strcmp(w->name, pin)) { 1276 if (!strcmp(w->name, pin)) {
1339 pr_debug("dapm: %s: pin %s\n", codec->name, pin); 1277 pr_debug("dapm: %s: pin %s\n", codec->name, pin);
1340 w->connected = status; 1278 w->connected = status;
1279 /* Allow disabling of forced pins */
1280 if (status == 0)
1281 w->force = 0;
1341 return 0; 1282 return 0;
1342 } 1283 }
1343 } 1284 }
@@ -1594,12 +1535,6 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
1594 unsigned int invert = mc->invert; 1535 unsigned int invert = mc->invert;
1595 unsigned int mask = (1 << fls(max)) - 1; 1536 unsigned int mask = (1 << fls(max)) - 1;
1596 1537
1597 /* return the saved value if we are powered down */
1598 if (widget->id == snd_soc_dapm_pga && !widget->power) {
1599 ucontrol->value.integer.value[0] = widget->saved_value;
1600 return 0;
1601 }
1602
1603 ucontrol->value.integer.value[0] = 1538 ucontrol->value.integer.value[0] =
1604 (snd_soc_read(widget->codec, reg) >> shift) & mask; 1539 (snd_soc_read(widget->codec, reg) >> shift) & mask;
1605 if (shift != rshift) 1540 if (shift != rshift)
@@ -1659,13 +1594,6 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1659 mutex_lock(&widget->codec->mutex); 1594 mutex_lock(&widget->codec->mutex);
1660 widget->value = val; 1595 widget->value = val;
1661 1596
1662 /* save volume value if the widget is powered down */
1663 if (widget->id == snd_soc_dapm_pga && !widget->power) {
1664 widget->saved_value = val;
1665 mutex_unlock(&widget->codec->mutex);
1666 return 1;
1667 }
1668
1669 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 1597 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
1670 if (val) 1598 if (val)
1671 /* new connection */ 1599 /* new connection */
@@ -2094,18 +2022,8 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
2094 w->active = 0; 2022 w->active = 0;
2095 break; 2023 break;
2096 case SND_SOC_DAPM_STREAM_SUSPEND: 2024 case SND_SOC_DAPM_STREAM_SUSPEND:
2097 if (w->active)
2098 w->suspend = 1;
2099 w->active = 0;
2100 break;
2101 case SND_SOC_DAPM_STREAM_RESUME: 2025 case SND_SOC_DAPM_STREAM_RESUME:
2102 if (w->suspend) {
2103 w->active = 1;
2104 w->suspend = 0;
2105 }
2106 break;
2107 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 2026 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
2108 break;
2109 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 2027 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
2110 break; 2028 break;
2111 } 2029 }
@@ -2135,6 +2053,36 @@ int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin)
2135EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 2053EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2136 2054
2137/** 2055/**
2056 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
2057 * @codec: SoC codec
2058 * @pin: pin name
2059 *
2060 * Enables input/output pin regardless of any other state. This is
2061 * intended for use with microphone bias supplies used in microphone
2062 * jack detection.
2063 *
2064 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2065 * do any widget power switching.
2066 */
2067int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin)
2068{
2069 struct snd_soc_dapm_widget *w;
2070
2071 list_for_each_entry(w, &codec->dapm_widgets, list) {
2072 if (!strcmp(w->name, pin)) {
2073 pr_debug("dapm: %s: pin %s\n", codec->name, pin);
2074 w->connected = 1;
2075 w->force = 1;
2076 return 0;
2077 }
2078 }
2079
2080 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin);
2081 return -EINVAL;
2082}
2083EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
2084
2085/**
2138 * snd_soc_dapm_disable_pin - disable pin. 2086 * snd_soc_dapm_disable_pin - disable pin.
2139 * @codec: SoC codec 2087 * @codec: SoC codec
2140 * @pin: pin name 2088 * @pin: pin name
@@ -2192,6 +2140,33 @@ int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin)
2192EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); 2140EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
2193 2141
2194/** 2142/**
2143 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
2144 * @codec: audio codec
2145 * @pin: audio signal pin endpoint (or start point)
2146 *
2147 * Mark the given endpoint or pin as ignoring suspend. When the
2148 * system is disabled a path between two endpoints flagged as ignoring
2149 * suspend will not be disabled. The path must already be enabled via
2150 * normal means at suspend time, it will not be turned on if it was not
2151 * already enabled.
2152 */
2153int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin)
2154{
2155 struct snd_soc_dapm_widget *w;
2156
2157 list_for_each_entry(w, &codec->dapm_widgets, list) {
2158 if (!strcmp(w->name, pin)) {
2159 w->ignore_suspend = 1;
2160 return 0;
2161 }
2162 }
2163
2164 pr_err("Unknown DAPM pin: %s\n", pin);
2165 return -EINVAL;
2166}
2167EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2168
2169/**
2195 * snd_soc_dapm_free - free dapm resources 2170 * snd_soc_dapm_free - free dapm resources
2196 * @socdev: SoC device 2171 * @socdev: SoC device
2197 * 2172 *
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 3c07a94c2e30..29159e1781d0 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -37,6 +37,7 @@ int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
37{ 37{
38 jack->card = card; 38 jack->card = card;
39 INIT_LIST_HEAD(&jack->pins); 39 INIT_LIST_HEAD(&jack->pins);
40 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
40 41
41 return snd_jack_new(card->codec->card, id, type, &jack->jack); 42 return snd_jack_new(card->codec->card, id, type, &jack->jack);
42} 43}
@@ -63,10 +64,9 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
63 int enable; 64 int enable;
64 int oldstatus; 65 int oldstatus;
65 66
66 if (!jack) { 67 if (!jack)
67 WARN_ON_ONCE(!jack);
68 return; 68 return;
69 } 69
70 codec = jack->card->codec; 70 codec = jack->card->codec;
71 71
72 mutex_lock(&codec->mutex); 72 mutex_lock(&codec->mutex);
@@ -93,6 +93,9 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
93 snd_soc_dapm_disable_pin(codec, pin->pin); 93 snd_soc_dapm_disable_pin(codec, pin->pin);
94 } 94 }
95 95
96 /* Report before the DAPM sync to help users updating micbias status */
97 blocking_notifier_call_chain(&jack->notifier, status, NULL);
98
96 snd_soc_dapm_sync(codec); 99 snd_soc_dapm_sync(codec);
97 100
98 snd_jack_report(jack->jack, status); 101 snd_jack_report(jack->jack, status);
@@ -143,6 +146,40 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
143} 146}
144EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins); 147EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins);
145 148
149/**
150 * snd_soc_jack_notifier_register - Register a notifier for jack status
151 *
152 * @jack: ASoC jack
153 * @nb: Notifier block to register
154 *
155 * Register for notification of the current status of the jack. Note
156 * that it is not possible to report additional jack events in the
157 * callback from the notifier, this is intended to support
158 * applications such as enabling electrical detection only when a
159 * mechanical detection event has occurred.
160 */
161void snd_soc_jack_notifier_register(struct snd_soc_jack *jack,
162 struct notifier_block *nb)
163{
164 blocking_notifier_chain_register(&jack->notifier, nb);
165}
166EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_register);
167
168/**
169 * snd_soc_jack_notifier_unregister - Unregister a notifier for jack status
170 *
171 * @jack: ASoC jack
172 * @nb: Notifier block to unregister
173 *
174 * Stop notifying for status changes.
175 */
176void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack,
177 struct notifier_block *nb)
178{
179 blocking_notifier_chain_unregister(&jack->notifier, nb);
180}
181EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_unregister);
182
146#ifdef CONFIG_GPIOLIB 183#ifdef CONFIG_GPIOLIB
147/* gpio detect */ 184/* gpio detect */
148static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) 185static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index c570ae3e6d55..44d6d2ec964f 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -22,8 +22,7 @@ config SND_USB_AUDIO
22 will be called snd-usb-audio. 22 will be called snd-usb-audio.
23 23
24config SND_USB_UA101 24config SND_USB_UA101
25 tristate "Edirol UA-101/UA-1000 driver (EXPERIMENTAL)" 25 tristate "Edirol UA-101/UA-1000 driver"
26 depends on EXPERIMENTAL
27 select SND_PCM 26 select SND_PCM
28 select SND_RAWMIDI 27 select SND_RAWMIDI
29 help 28 help
@@ -65,6 +64,7 @@ config SND_USB_CAIAQ
65 * Native Instruments Audio 8 DJ 64 * Native Instruments Audio 8 DJ
66 * Native Instruments Guitar Rig Session I/O 65 * Native Instruments Guitar Rig Session I/O
67 * Native Instruments Guitar Rig mobile 66 * Native Instruments Guitar Rig mobile
67 * Native Instruments Traktor Kontrol X1
68 68
69 To compile this driver as a module, choose M here: the module 69 To compile this driver as a module, choose M here: the module
70 will be called snd-usb-caiaq. 70 will be called snd-usb-caiaq.
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 5bf64aef9558..e7ac7f493a8f 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -2,14 +2,24 @@
2# Makefile for ALSA 2# Makefile for ALSA
3# 3#
4 4
5snd-usb-audio-objs := usbaudio.o usbmixer.o 5snd-usb-audio-objs := card.o \
6snd-usb-lib-objs := usbmidi.o 6 mixer.o \
7snd-ua101-objs := ua101.o 7 mixer_quirks.o \
8 proc.o \
9 quirks.o \
10 format.o \
11 endpoint.o \
12 urb.o \
13 pcm.o \
14 helper.o
15
16snd-usbmidi-lib-objs := midi.o
8 17
9# Toplevel Module Dependency 18# Toplevel Module Dependency
10obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o 19obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usbmidi-lib.o
11obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o snd-usb-lib.o 20
12obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o 21obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
13obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o 22obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
23obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
14 24
15obj-$(CONFIG_SND) += usx2y/ caiaq/ 25obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c
index 537102ba6b9d..36ed703a7416 100644
--- a/sound/usb/caiaq/control.c
+++ b/sound/usb/caiaq/control.c
@@ -35,33 +35,41 @@ static int control_info(struct snd_kcontrol *kcontrol,
35 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 35 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
36 int pos = kcontrol->private_value; 36 int pos = kcontrol->private_value;
37 int is_intval = pos & CNT_INTVAL; 37 int is_intval = pos & CNT_INTVAL;
38 unsigned int id = dev->chip.usb_id; 38 int maxval = 63;
39 39
40 uinfo->count = 1; 40 uinfo->count = 1;
41 pos &= ~CNT_INTVAL; 41 pos &= ~CNT_INTVAL;
42 42
43 if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ) 43 switch (dev->chip.usb_id) {
44 && (pos == 0)) { 44 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
45 /* current input mode of A8DJ */ 45 if (pos == 0) {
46 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 46 /* current input mode of A8DJ */
47 uinfo->value.integer.min = 0; 47 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
48 uinfo->value.integer.max = 2; 48 uinfo->value.integer.min = 0;
49 return 0; 49 uinfo->value.integer.max = 2;
50 } 50 return 0;
51 }
52 break;
51 53
52 if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ) 54 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
53 && (pos == 0)) { 55 if (pos == 0) {
54 /* current input mode of A4DJ */ 56 /* current input mode of A4DJ */
55 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 57 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
56 uinfo->value.integer.min = 0; 58 uinfo->value.integer.min = 0;
57 uinfo->value.integer.max = 1; 59 uinfo->value.integer.max = 1;
58 return 0; 60 return 0;
61 }
62 break;
63
64 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
65 maxval = 127;
66 break;
59 } 67 }
60 68
61 if (is_intval) { 69 if (is_intval) {
62 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 70 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
63 uinfo->value.integer.min = 0; 71 uinfo->value.integer.min = 0;
64 uinfo->value.integer.max = 64; 72 uinfo->value.integer.max = maxval;
65 } else { 73 } else {
66 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 74 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
67 uinfo->value.integer.min = 0; 75 uinfo->value.integer.min = 0;
@@ -102,9 +110,10 @@ static int control_put(struct snd_kcontrol *kcontrol,
102 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); 110 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
103 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 111 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
104 int pos = kcontrol->private_value; 112 int pos = kcontrol->private_value;
113 unsigned char cmd = EP1_CMD_WRITE_IO;
105 114
106 if (dev->chip.usb_id == 115 switch (dev->chip.usb_id) {
107 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) { 116 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): {
108 /* A4DJ has only one control */ 117 /* A4DJ has only one control */
109 /* do not expose hardware input mode 0 */ 118 /* do not expose hardware input mode 0 */
110 dev->control_state[0] = ucontrol->value.integer.value[0] + 1; 119 dev->control_state[0] = ucontrol->value.integer.value[0] + 1;
@@ -113,10 +122,15 @@ static int control_put(struct snd_kcontrol *kcontrol,
113 return 1; 122 return 1;
114 } 123 }
115 124
125 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
126 cmd = EP1_CMD_DIMM_LEDS;
127 break;
128 }
129
116 if (pos & CNT_INTVAL) { 130 if (pos & CNT_INTVAL) {
117 dev->control_state[pos & ~CNT_INTVAL] 131 dev->control_state[pos & ~CNT_INTVAL]
118 = ucontrol->value.integer.value[0]; 132 = ucontrol->value.integer.value[0];
119 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, 133 snd_usb_caiaq_send_command(dev, cmd,
120 dev->control_state, sizeof(dev->control_state)); 134 dev->control_state, sizeof(dev->control_state));
121 } else { 135 } else {
122 if (ucontrol->value.integer.value[0]) 136 if (ucontrol->value.integer.value[0])
@@ -124,7 +138,7 @@ static int control_put(struct snd_kcontrol *kcontrol,
124 else 138 else
125 dev->control_state[pos / 8] &= ~(1 << (pos % 8)); 139 dev->control_state[pos / 8] &= ~(1 << (pos % 8));
126 140
127 snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, 141 snd_usb_caiaq_send_command(dev, cmd,
128 dev->control_state, sizeof(dev->control_state)); 142 dev->control_state, sizeof(dev->control_state));
129 } 143 }
130 144
@@ -273,6 +287,43 @@ static struct caiaq_controller a4dj_controller[] = {
273 { "Current input mode", 0 | CNT_INTVAL } 287 { "Current input mode", 0 | CNT_INTVAL }
274}; 288};
275 289
290static struct caiaq_controller kontrolx1_controller[] = {
291 { "LED FX A: ON", 7 | CNT_INTVAL },
292 { "LED FX A: 1", 6 | CNT_INTVAL },
293 { "LED FX A: 2", 5 | CNT_INTVAL },
294 { "LED FX A: 3", 4 | CNT_INTVAL },
295 { "LED FX B: ON", 3 | CNT_INTVAL },
296 { "LED FX B: 1", 2 | CNT_INTVAL },
297 { "LED FX B: 2", 1 | CNT_INTVAL },
298 { "LED FX B: 3", 0 | CNT_INTVAL },
299
300 { "LED Hotcue", 28 | CNT_INTVAL },
301 { "LED Shift (white)", 29 | CNT_INTVAL },
302 { "LED Shift (green)", 30 | CNT_INTVAL },
303
304 { "LED Deck A: FX1", 24 | CNT_INTVAL },
305 { "LED Deck A: FX2", 25 | CNT_INTVAL },
306 { "LED Deck A: IN", 17 | CNT_INTVAL },
307 { "LED Deck A: OUT", 16 | CNT_INTVAL },
308 { "LED Deck A: < BEAT", 19 | CNT_INTVAL },
309 { "LED Deck A: BEAT >", 18 | CNT_INTVAL },
310 { "LED Deck A: CUE/ABS", 21 | CNT_INTVAL },
311 { "LED Deck A: CUP/REL", 20 | CNT_INTVAL },
312 { "LED Deck A: PLAY", 23 | CNT_INTVAL },
313 { "LED Deck A: SYNC", 22 | CNT_INTVAL },
314
315 { "LED Deck B: FX1", 26 | CNT_INTVAL },
316 { "LED Deck B: FX2", 27 | CNT_INTVAL },
317 { "LED Deck B: IN", 15 | CNT_INTVAL },
318 { "LED Deck B: OUT", 14 | CNT_INTVAL },
319 { "LED Deck B: < BEAT", 13 | CNT_INTVAL },
320 { "LED Deck B: BEAT >", 12 | CNT_INTVAL },
321 { "LED Deck B: CUE/ABS", 11 | CNT_INTVAL },
322 { "LED Deck B: CUP/REL", 10 | CNT_INTVAL },
323 { "LED Deck B: PLAY", 9 | CNT_INTVAL },
324 { "LED Deck B: SYNC", 8 | CNT_INTVAL },
325};
326
276static int __devinit add_controls(struct caiaq_controller *c, int num, 327static int __devinit add_controls(struct caiaq_controller *c, int num,
277 struct snd_usb_caiaqdev *dev) 328 struct snd_usb_caiaqdev *dev)
278{ 329{
@@ -321,10 +372,16 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
321 ret = add_controls(a8dj_controller, 372 ret = add_controls(a8dj_controller,
322 ARRAY_SIZE(a8dj_controller), dev); 373 ARRAY_SIZE(a8dj_controller), dev);
323 break; 374 break;
375
324 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): 376 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
325 ret = add_controls(a4dj_controller, 377 ret = add_controls(a4dj_controller,
326 ARRAY_SIZE(a4dj_controller), dev); 378 ARRAY_SIZE(a4dj_controller), dev);
327 break; 379 break;
380
381 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
382 ret = add_controls(kontrolx1_controller,
383 ARRAY_SIZE(kontrolx1_controller), dev);
384 break;
328 } 385 }
329 386
330 return ret; 387 return ret;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index afc5aeb68005..805271827675 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -47,7 +47,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
47 "{Native Instruments, Audio 4 DJ}," 47 "{Native Instruments, Audio 4 DJ},"
48 "{Native Instruments, Audio 8 DJ}," 48 "{Native Instruments, Audio 8 DJ},"
49 "{Native Instruments, Session I/O}," 49 "{Native Instruments, Session I/O},"
50 "{Native Instruments, GuitarRig mobile}"); 50 "{Native Instruments, GuitarRig mobile}"
51 "{Native Instruments, Traktor Kontrol X1}");
51 52
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 53static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
53static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 54static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
@@ -128,6 +129,11 @@ static struct usb_device_id snd_usb_id_table[] = {
128 .idVendor = USB_VID_NATIVEINSTRUMENTS, 129 .idVendor = USB_VID_NATIVEINSTRUMENTS,
129 .idProduct = USB_PID_AUDIO2DJ 130 .idProduct = USB_PID_AUDIO2DJ
130 }, 131 },
132 {
133 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
134 .idVendor = USB_VID_NATIVEINSTRUMENTS,
135 .idProduct = USB_PID_TRAKTORKONTROLX1
136 },
131 { /* terminator */ } 137 { /* terminator */ }
132}; 138};
133 139
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index 44e3edf88bef..f1117ecc84fd 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -5,18 +5,20 @@
5 5
6#define USB_VID_NATIVEINSTRUMENTS 0x17cc 6#define USB_VID_NATIVEINSTRUMENTS 0x17cc
7 7
8#define USB_PID_RIGKONTROL2 0x1969 8#define USB_PID_RIGKONTROL2 0x1969
9#define USB_PID_RIGKONTROL3 0x1940 9#define USB_PID_RIGKONTROL3 0x1940
10#define USB_PID_KORECONTROLLER 0x4711 10#define USB_PID_KORECONTROLLER 0x4711
11#define USB_PID_KORECONTROLLER2 0x4712 11#define USB_PID_KORECONTROLLER2 0x4712
12#define USB_PID_AK1 0x0815 12#define USB_PID_AK1 0x0815
13#define USB_PID_AUDIO2DJ 0x041c 13#define USB_PID_AUDIO2DJ 0x041c
14#define USB_PID_AUDIO4DJ 0x0839 14#define USB_PID_AUDIO4DJ 0x0839
15#define USB_PID_AUDIO8DJ 0x1978 15#define USB_PID_AUDIO8DJ 0x1978
16#define USB_PID_SESSIONIO 0x1915 16#define USB_PID_SESSIONIO 0x1915
17#define USB_PID_GUITARRIGMOBILE 0x0d8d 17#define USB_PID_GUITARRIGMOBILE 0x0d8d
18#define USB_PID_TRAKTORKONTROLX1 0x2305
18 19
19#define EP1_BUFSIZE 64 20#define EP1_BUFSIZE 64
21#define EP4_BUFSIZE 512
20#define CAIAQ_USB_STR_LEN 0xff 22#define CAIAQ_USB_STR_LEN 0xff
21#define MAX_STREAMS 32 23#define MAX_STREAMS 32
22 24
@@ -104,6 +106,8 @@ struct snd_usb_caiaqdev {
104 struct input_dev *input_dev; 106 struct input_dev *input_dev;
105 char phys[64]; /* physical device path */ 107 char phys[64]; /* physical device path */
106 unsigned short keycode[64]; 108 unsigned short keycode[64];
109 struct urb *ep4_in_urb;
110 unsigned char ep4_in_buf[EP4_BUFSIZE];
107#endif 111#endif
108 112
109 /* ALSA */ 113 /* ALSA */
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index a48d309bd94c..8bbfbfd4c658 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -16,9 +16,11 @@
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17*/ 17*/
18 18
19#include <linux/gfp.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/usb.h> 21#include <linux/usb.h>
21#include <linux/usb/input.h> 22#include <linux/usb/input.h>
23#include <sound/core.h>
22#include <sound/pcm.h> 24#include <sound/pcm.h>
23 25
24#include "device.h" 26#include "device.h"
@@ -65,6 +67,8 @@ static unsigned short keycode_kore[] = {
65 KEY_BRL_DOT5 67 KEY_BRL_DOT5
66}; 68};
67 69
70#define KONTROLX1_INPUTS 40
71
68#define DEG90 (range / 2) 72#define DEG90 (range / 2)
69#define DEG180 (range) 73#define DEG180 (range)
70#define DEG270 (DEG90 + DEG180) 74#define DEG270 (DEG90 + DEG180)
@@ -162,6 +166,17 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
162 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); 166 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]);
163 input_sync(input_dev); 167 input_sync(input_dev);
164 break; 168 break;
169 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
170 input_report_abs(input_dev, ABS_HAT0X, (buf[8] << 8) | buf[9]);
171 input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]);
172 input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]);
173 input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]);
174 input_report_abs(input_dev, ABS_HAT2X, (buf[15] << 8) | buf[15]);
175 input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]);
176 input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]);
177 input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]);
178 input_sync(input_dev);
179 break;
165 } 180 }
166} 181}
167 182
@@ -201,7 +216,7 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
201} 216}
202 217
203static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, 218static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
204 char *buf, unsigned int len) 219 unsigned char *buf, unsigned int len)
205{ 220{
206 struct input_dev *input_dev = dev->input_dev; 221 struct input_dev *input_dev = dev->input_dev;
207 unsigned short *keycode = input_dev->keycode; 222 unsigned short *keycode = input_dev->keycode;
@@ -218,15 +233,84 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
218 input_report_key(input_dev, keycode[i], 233 input_report_key(input_dev, keycode[i],
219 buf[i / 8] & (1 << (i % 8))); 234 buf[i / 8] & (1 << (i % 8)));
220 235
221 if (dev->chip.usb_id == 236 switch (dev->chip.usb_id) {
222 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER) || 237 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
223 dev->chip.usb_id == 238 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
224 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2))
225 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]); 239 input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]);
240 break;
241 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
242 /* rotary encoders */
243 input_report_abs(dev->input_dev, ABS_X, buf[5] & 0xf);
244 input_report_abs(dev->input_dev, ABS_Y, buf[5] >> 4);
245 input_report_abs(dev->input_dev, ABS_Z, buf[6] & 0xf);
246 input_report_abs(dev->input_dev, ABS_MISC, buf[6] >> 4);
247 break;
248 }
226 249
227 input_sync(input_dev); 250 input_sync(input_dev);
228} 251}
229 252
253static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
254{
255 struct snd_usb_caiaqdev *dev = urb->context;
256 unsigned char *buf = urb->transfer_buffer;
257 int ret;
258
259 if (urb->status || !dev || urb != dev->ep4_in_urb)
260 return;
261
262 if (urb->actual_length < 24)
263 goto requeue;
264
265 switch (dev->chip.usb_id) {
266 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
267 if (buf[0] & 0x3)
268 snd_caiaq_input_read_io(dev, buf + 1, 7);
269
270 if (buf[0] & 0x4)
271 snd_caiaq_input_read_analog(dev, buf + 8, 16);
272
273 break;
274 }
275
276requeue:
277 dev->ep4_in_urb->actual_length = 0;
278 ret = usb_submit_urb(dev->ep4_in_urb, GFP_ATOMIC);
279 if (ret < 0)
280 log("unable to submit urb. OOM!?\n");
281}
282
283static int snd_usb_caiaq_input_open(struct input_dev *idev)
284{
285 struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
286
287 if (!dev)
288 return -EINVAL;
289
290 switch (dev->chip.usb_id) {
291 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
292 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
293 return -EIO;
294 break;
295 }
296
297 return 0;
298}
299
300static void snd_usb_caiaq_input_close(struct input_dev *idev)
301{
302 struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
303
304 if (!dev)
305 return;
306
307 switch (dev->chip.usb_id) {
308 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
309 usb_kill_urb(dev->ep4_in_urb);
310 break;
311 }
312}
313
230void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, 314void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev,
231 char *buf, 315 char *buf,
232 unsigned int len) 316 unsigned int len)
@@ -251,7 +335,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
251{ 335{
252 struct usb_device *usb_dev = dev->chip.dev; 336 struct usb_device *usb_dev = dev->chip.dev;
253 struct input_dev *input; 337 struct input_dev *input;
254 int i, ret; 338 int i, ret = 0;
255 339
256 input = input_allocate_device(); 340 input = input_allocate_device();
257 if (!input) 341 if (!input)
@@ -265,7 +349,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
265 usb_to_input_id(usb_dev, &input->id); 349 usb_to_input_id(usb_dev, &input->id);
266 input->dev.parent = &usb_dev->dev; 350 input->dev.parent = &usb_dev->dev;
267 351
268 switch (dev->chip.usb_id) { 352 input_set_drvdata(input, dev);
353
354 switch (dev->chip.usb_id) {
269 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 355 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
270 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 356 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
271 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | 357 input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
@@ -326,25 +412,72 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
326 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); 412 input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
327 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); 413 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
328 break; 414 break;
415 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
416 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
417 input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
418 BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
419 BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
420 BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
421 BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
422 BIT_MASK(ABS_Z);
423 input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
424 BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLX1_INPUTS);
425 for (i = 0; i < KONTROLX1_INPUTS; i++)
426 dev->keycode[i] = BTN_MISC + i;
427 input->keycodemax = KONTROLX1_INPUTS;
428
429 /* analog potentiometers */
430 input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10);
431 input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10);
432 input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10);
433 input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10);
434 input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10);
435 input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10);
436 input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10);
437 input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10);
438
439 /* rotary encoders */
440 input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1);
441 input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1);
442 input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1);
443 input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1);
444
445 dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
446 if (!dev->ep4_in_urb) {
447 ret = -ENOMEM;
448 goto exit_free_idev;
449 }
450
451 usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
452 usb_rcvbulkpipe(usb_dev, 0x4),
453 dev->ep4_in_buf, EP4_BUFSIZE,
454 snd_usb_caiaq_ep4_reply_dispatch, dev);
455
456 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
457
458 break;
329 default: 459 default:
330 /* no input methods supported on this device */ 460 /* no input methods supported on this device */
331 input_free_device(input); 461 goto exit_free_idev;
332 return 0;
333 } 462 }
334 463
464 input->open = snd_usb_caiaq_input_open;
465 input->close = snd_usb_caiaq_input_close;
335 input->keycode = dev->keycode; 466 input->keycode = dev->keycode;
336 input->keycodesize = sizeof(unsigned short); 467 input->keycodesize = sizeof(unsigned short);
337 for (i = 0; i < input->keycodemax; i++) 468 for (i = 0; i < input->keycodemax; i++)
338 __set_bit(dev->keycode[i], input->keybit); 469 __set_bit(dev->keycode[i], input->keybit);
339 470
340 ret = input_register_device(input); 471 ret = input_register_device(input);
341 if (ret < 0) { 472 if (ret < 0)
342 input_free_device(input); 473 goto exit_free_idev;
343 return ret;
344 }
345 474
346 dev->input_dev = input; 475 dev->input_dev = input;
347 return 0; 476 return 0;
477
478exit_free_idev:
479 input_free_device(input);
480 return ret;
348} 481}
349 482
350void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) 483void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
@@ -352,6 +485,10 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
352 if (!dev || !dev->input_dev) 485 if (!dev || !dev->input_dev)
353 return; 486 return;
354 487
488 usb_kill_urb(dev->ep4_in_urb);
489 usb_free_urb(dev->ep4_in_urb);
490 dev->ep4_in_urb = NULL;
491
355 input_unregister_device(dev->input_dev); 492 input_unregister_device(dev->input_dev);
356 dev->input_dev = NULL; 493 dev->input_dev = NULL;
357} 494}
diff --git a/sound/usb/card.c b/sound/usb/card.c
new file mode 100644
index 000000000000..da1346bd4856
--- /dev/null
+++ b/sound/usb/card.c
@@ -0,0 +1,652 @@
1/*
2 * (Tentative) USB Audio Driver for ALSA
3 *
4 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
5 *
6 * Many codes borrowed from audio.c by
7 * Alan Cox (alan@lxorguk.ukuu.org.uk)
8 * Thomas Sailer (sailer@ife.ee.ethz.ch)
9 *
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 *
26 * NOTES:
27 *
28 * - async unlink should be used for avoiding the sleep inside lock.
29 * 2.4.22 usb-uhci seems buggy for async unlinking and results in
30 * oops. in such a cse, pass async_unlink=0 option.
31 * - the linked URBs would be preferred but not used so far because of
32 * the instability of unlinking.
33 * - type II is not supported properly. there is no device which supports
34 * this type *correctly*. SB extigy looks as if it supports, but it's
35 * indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
36 */
37
38
39#include <linux/bitops.h>
40#include <linux/init.h>
41#include <linux/list.h>
42#include <linux/slab.h>
43#include <linux/string.h>
44#include <linux/usb.h>
45#include <linux/moduleparam.h>
46#include <linux/mutex.h>
47#include <linux/usb/audio.h>
48#include <linux/usb/audio-v2.h>
49
50#include <sound/core.h>
51#include <sound/info.h>
52#include <sound/pcm.h>
53#include <sound/pcm_params.h>
54#include <sound/initval.h>
55
56#include "usbaudio.h"
57#include "card.h"
58#include "midi.h"
59#include "mixer.h"
60#include "proc.h"
61#include "quirks.h"
62#include "endpoint.h"
63#include "helper.h"
64#include "debug.h"
65#include "pcm.h"
66#include "urb.h"
67#include "format.h"
68
69MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
70MODULE_DESCRIPTION("USB Audio");
71MODULE_LICENSE("GPL");
72MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
73
74
75static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
76static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
77static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
78/* Vendor/product IDs for this card */
79static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
80static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
81static int nrpacks = 8; /* max. number of packets per urb */
82static int async_unlink = 1;
83static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
84static int ignore_ctl_error;
85
86module_param_array(index, int, NULL, 0444);
87MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
88module_param_array(id, charp, NULL, 0444);
89MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
90module_param_array(enable, bool, NULL, 0444);
91MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
92module_param_array(vid, int, NULL, 0444);
93MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
94module_param_array(pid, int, NULL, 0444);
95MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
96module_param(nrpacks, int, 0644);
97MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
98module_param(async_unlink, bool, 0444);
99MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
100module_param_array(device_setup, int, NULL, 0444);
101MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
102module_param(ignore_ctl_error, bool, 0444);
103MODULE_PARM_DESC(ignore_ctl_error,
104 "Ignore errors from USB controller for mixer interfaces.");
105
106/*
107 * we keep the snd_usb_audio_t instances by ourselves for merging
108 * the all interfaces on the same card as one sound device.
109 */
110
111static DEFINE_MUTEX(register_mutex);
112static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
113static struct usb_driver usb_audio_driver;
114
115/*
116 * disconnect streams
117 * called from snd_usb_audio_disconnect()
118 */
119static void snd_usb_stream_disconnect(struct list_head *head)
120{
121 int idx;
122 struct snd_usb_stream *as;
123 struct snd_usb_substream *subs;
124
125 as = list_entry(head, struct snd_usb_stream, list);
126 for (idx = 0; idx < 2; idx++) {
127 subs = &as->substream[idx];
128 if (!subs->num_formats)
129 return;
130 snd_usb_release_substream_urbs(subs, 1);
131 subs->interface = -1;
132 }
133}
134
135static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
136{
137 struct usb_device *dev = chip->dev;
138 struct usb_host_interface *alts;
139 struct usb_interface_descriptor *altsd;
140 struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
141
142 if (!iface) {
143 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
144 dev->devnum, ctrlif, interface);
145 return -EINVAL;
146 }
147
148 if (usb_interface_claimed(iface)) {
149 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
150 dev->devnum, ctrlif, interface);
151 return -EINVAL;
152 }
153
154 alts = &iface->altsetting[0];
155 altsd = get_iface_desc(alts);
156 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
157 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
158 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
159 int err = snd_usbmidi_create(chip->card, iface,
160 &chip->midi_list, NULL);
161 if (err < 0) {
162 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
163 dev->devnum, ctrlif, interface);
164 return -EINVAL;
165 }
166 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
167
168 return 0;
169 }
170
171 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
172 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
173 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
174 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
175 dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
176 /* skip non-supported classes */
177 return -EINVAL;
178 }
179
180 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
181 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
182 return -EINVAL;
183 }
184
185 if (! snd_usb_parse_audio_endpoints(chip, interface)) {
186 usb_set_interface(dev, interface, 0); /* reset the current interface */
187 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
188 return -EINVAL;
189 }
190
191 return 0;
192}
193
194/*
195 * parse audio control descriptor and create pcm/midi streams
196 */
197static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
198{
199 struct usb_device *dev = chip->dev;
200 struct usb_host_interface *host_iface;
201 struct usb_interface_descriptor *altsd;
202 void *control_header;
203 int i, protocol;
204
205 /* find audiocontrol interface */
206 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
207 control_header = snd_usb_find_csint_desc(host_iface->extra,
208 host_iface->extralen,
209 NULL, UAC_HEADER);
210 altsd = get_iface_desc(host_iface);
211 protocol = altsd->bInterfaceProtocol;
212
213 if (!control_header) {
214 snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
215 return -EINVAL;
216 }
217
218 switch (protocol) {
219 case UAC_VERSION_1: {
220 struct uac_ac_header_descriptor_v1 *h1 = control_header;
221
222 if (!h1->bInCollection) {
223 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
224 return -EINVAL;
225 }
226
227 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
228 snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
229 return -EINVAL;
230 }
231
232 for (i = 0; i < h1->bInCollection; i++)
233 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
234
235 break;
236 }
237
238 case UAC_VERSION_2: {
239 struct uac_clock_source_descriptor *cs;
240 struct usb_interface_assoc_descriptor *assoc =
241 usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
242
243 if (!assoc) {
244 snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
245 return -EINVAL;
246 }
247
248 /* FIXME: for now, we expect there is at least one clock source
249 * descriptor and we always take the first one.
250 * We should properly support devices with multiple clock sources,
251 * clock selectors and sample rate conversion units. */
252
253 cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen,
254 NULL, UAC2_CLOCK_SOURCE);
255
256 if (!cs) {
257 snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n");
258 return -EINVAL;
259 }
260
261 chip->clock_id = cs->bClockID;
262
263 for (i = 0; i < assoc->bInterfaceCount; i++) {
264 int intf = assoc->bFirstInterface + i;
265
266 if (intf != ctrlif)
267 snd_usb_create_stream(chip, ctrlif, intf);
268 }
269
270 break;
271 }
272
273 default:
274 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
275 return -EINVAL;
276 }
277
278 return 0;
279}
280
281/*
282 * free the chip instance
283 *
284 * here we have to do not much, since pcm and controls are already freed
285 *
286 */
287
288static int snd_usb_audio_free(struct snd_usb_audio *chip)
289{
290 kfree(chip);
291 return 0;
292}
293
294static int snd_usb_audio_dev_free(struct snd_device *device)
295{
296 struct snd_usb_audio *chip = device->device_data;
297 return snd_usb_audio_free(chip);
298}
299
300
301/*
302 * create a chip instance and set its names.
303 */
304static int snd_usb_audio_create(struct usb_device *dev, int idx,
305 const struct snd_usb_audio_quirk *quirk,
306 struct snd_usb_audio **rchip)
307{
308 struct snd_card *card;
309 struct snd_usb_audio *chip;
310 int err, len;
311 char component[14];
312 static struct snd_device_ops ops = {
313 .dev_free = snd_usb_audio_dev_free,
314 };
315
316 *rchip = NULL;
317
318 if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
319 snd_usb_get_speed(dev) != USB_SPEED_FULL &&
320 snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
321 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
322 return -ENXIO;
323 }
324
325 err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
326 if (err < 0) {
327 snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
328 return err;
329 }
330
331 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
332 if (! chip) {
333 snd_card_free(card);
334 return -ENOMEM;
335 }
336
337 chip->index = idx;
338 chip->dev = dev;
339 chip->card = card;
340 chip->setup = device_setup[idx];
341 chip->nrpacks = nrpacks;
342 chip->async_unlink = async_unlink;
343
344 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
345 le16_to_cpu(dev->descriptor.idProduct));
346 INIT_LIST_HEAD(&chip->pcm_list);
347 INIT_LIST_HEAD(&chip->midi_list);
348 INIT_LIST_HEAD(&chip->mixer_list);
349
350 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
351 snd_usb_audio_free(chip);
352 snd_card_free(card);
353 return err;
354 }
355
356 strcpy(card->driver, "USB-Audio");
357 sprintf(component, "USB%04x:%04x",
358 USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
359 snd_component_add(card, component);
360
361 /* retrieve the device string as shortname */
362 if (quirk && quirk->product_name) {
363 strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
364 } else {
365 if (!dev->descriptor.iProduct ||
366 usb_string(dev, dev->descriptor.iProduct,
367 card->shortname, sizeof(card->shortname)) <= 0) {
368 /* no name available from anywhere, so use ID */
369 sprintf(card->shortname, "USB Device %#04x:%#04x",
370 USB_ID_VENDOR(chip->usb_id),
371 USB_ID_PRODUCT(chip->usb_id));
372 }
373 }
374
375 /* retrieve the vendor and device strings as longname */
376 if (quirk && quirk->vendor_name) {
377 len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
378 } else {
379 if (dev->descriptor.iManufacturer)
380 len = usb_string(dev, dev->descriptor.iManufacturer,
381 card->longname, sizeof(card->longname));
382 else
383 len = 0;
384 /* we don't really care if there isn't any vendor string */
385 }
386 if (len > 0)
387 strlcat(card->longname, " ", sizeof(card->longname));
388
389 strlcat(card->longname, card->shortname, sizeof(card->longname));
390
391 len = strlcat(card->longname, " at ", sizeof(card->longname));
392
393 if (len < sizeof(card->longname))
394 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
395
396 strlcat(card->longname,
397 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
398 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
399 ", high speed",
400 sizeof(card->longname));
401
402 snd_usb_audio_create_proc(chip);
403
404 *rchip = chip;
405 return 0;
406}
407
408/*
409 * probe the active usb device
410 *
411 * note that this can be called multiple times per a device, when it
412 * includes multiple audio control interfaces.
413 *
414 * thus we check the usb device pointer and creates the card instance
415 * only at the first time. the successive calls of this function will
416 * append the pcm interface to the corresponding card.
417 */
418static void *snd_usb_audio_probe(struct usb_device *dev,
419 struct usb_interface *intf,
420 const struct usb_device_id *usb_id)
421{
422 const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
423 int i, err;
424 struct snd_usb_audio *chip;
425 struct usb_host_interface *alts;
426 int ifnum;
427 u32 id;
428
429 alts = &intf->altsetting[0];
430 ifnum = get_iface_desc(alts)->bInterfaceNumber;
431 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
432 le16_to_cpu(dev->descriptor.idProduct));
433 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
434 goto __err_val;
435
436 if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)
437 goto __err_val;
438
439 /*
440 * found a config. now register to ALSA
441 */
442
443 /* check whether it's already registered */
444 chip = NULL;
445 mutex_lock(&register_mutex);
446 for (i = 0; i < SNDRV_CARDS; i++) {
447 if (usb_chip[i] && usb_chip[i]->dev == dev) {
448 if (usb_chip[i]->shutdown) {
449 snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
450 goto __error;
451 }
452 chip = usb_chip[i];
453 break;
454 }
455 }
456 if (! chip) {
457 /* it's a fresh one.
458 * now look for an empty slot and create a new card instance
459 */
460 for (i = 0; i < SNDRV_CARDS; i++)
461 if (enable[i] && ! usb_chip[i] &&
462 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
463 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
464 if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
465 goto __error;
466 }
467 snd_card_set_dev(chip->card, &intf->dev);
468 break;
469 }
470 if (!chip) {
471 printk(KERN_ERR "no available usb audio device\n");
472 goto __error;
473 }
474 }
475
476 chip->txfr_quirk = 0;
477 err = 1; /* continue */
478 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
479 /* need some special handlings */
480 if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)
481 goto __error;
482 }
483
484 if (err > 0) {
485 /* create normal USB audio interfaces */
486 if (snd_usb_create_streams(chip, ifnum) < 0 ||
487 snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
488 goto __error;
489 }
490 }
491
492 /* we are allowed to call snd_card_register() many times */
493 if (snd_card_register(chip->card) < 0) {
494 goto __error;
495 }
496
497 usb_chip[chip->index] = chip;
498 chip->num_interfaces++;
499 mutex_unlock(&register_mutex);
500 return chip;
501
502 __error:
503 if (chip && !chip->num_interfaces)
504 snd_card_free(chip->card);
505 mutex_unlock(&register_mutex);
506 __err_val:
507 return NULL;
508}
509
510/*
511 * we need to take care of counter, since disconnection can be called also
512 * many times as well as usb_audio_probe().
513 */
514static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
515{
516 struct snd_usb_audio *chip;
517 struct snd_card *card;
518 struct list_head *p;
519
520 if (ptr == (void *)-1L)
521 return;
522
523 chip = ptr;
524 card = chip->card;
525 mutex_lock(&register_mutex);
526 chip->shutdown = 1;
527 chip->num_interfaces--;
528 if (chip->num_interfaces <= 0) {
529 snd_card_disconnect(card);
530 /* release the pcm resources */
531 list_for_each(p, &chip->pcm_list) {
532 snd_usb_stream_disconnect(p);
533 }
534 /* release the midi resources */
535 list_for_each(p, &chip->midi_list) {
536 snd_usbmidi_disconnect(p);
537 }
538 /* release mixer resources */
539 list_for_each(p, &chip->mixer_list) {
540 snd_usb_mixer_disconnect(p);
541 }
542 usb_chip[chip->index] = NULL;
543 mutex_unlock(&register_mutex);
544 snd_card_free_when_closed(card);
545 } else {
546 mutex_unlock(&register_mutex);
547 }
548}
549
550/*
551 * new 2.5 USB kernel API
552 */
553static int usb_audio_probe(struct usb_interface *intf,
554 const struct usb_device_id *id)
555{
556 void *chip;
557 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
558 if (chip) {
559 usb_set_intfdata(intf, chip);
560 return 0;
561 } else
562 return -EIO;
563}
564
565static void usb_audio_disconnect(struct usb_interface *intf)
566{
567 snd_usb_audio_disconnect(interface_to_usbdev(intf),
568 usb_get_intfdata(intf));
569}
570
571#ifdef CONFIG_PM
572static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
573{
574 struct snd_usb_audio *chip = usb_get_intfdata(intf);
575 struct list_head *p;
576 struct snd_usb_stream *as;
577
578 if (chip == (void *)-1L)
579 return 0;
580
581 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
582 if (!chip->num_suspended_intf++) {
583 list_for_each(p, &chip->pcm_list) {
584 as = list_entry(p, struct snd_usb_stream, list);
585 snd_pcm_suspend_all(as->pcm);
586 }
587 }
588
589 return 0;
590}
591
592static int usb_audio_resume(struct usb_interface *intf)
593{
594 struct snd_usb_audio *chip = usb_get_intfdata(intf);
595
596 if (chip == (void *)-1L)
597 return 0;
598 if (--chip->num_suspended_intf)
599 return 0;
600 /*
601 * ALSA leaves material resumption to user space
602 * we just notify
603 */
604
605 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
606
607 return 0;
608}
609#else
610#define usb_audio_suspend NULL
611#define usb_audio_resume NULL
612#endif /* CONFIG_PM */
613
614static struct usb_device_id usb_audio_ids [] = {
615#include "quirks-table.h"
616 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
617 .bInterfaceClass = USB_CLASS_AUDIO,
618 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
619 { } /* Terminating entry */
620};
621
622MODULE_DEVICE_TABLE (usb, usb_audio_ids);
623
624/*
625 * entry point for linux usb interface
626 */
627
628static struct usb_driver usb_audio_driver = {
629 .name = "snd-usb-audio",
630 .probe = usb_audio_probe,
631 .disconnect = usb_audio_disconnect,
632 .suspend = usb_audio_suspend,
633 .resume = usb_audio_resume,
634 .id_table = usb_audio_ids,
635};
636
637static int __init snd_usb_audio_init(void)
638{
639 if (nrpacks < 1 || nrpacks > MAX_PACKS) {
640 printk(KERN_WARNING "invalid nrpacks value.\n");
641 return -EINVAL;
642 }
643 return usb_register(&usb_audio_driver);
644}
645
646static void __exit snd_usb_audio_cleanup(void)
647{
648 usb_deregister(&usb_audio_driver);
649}
650
651module_init(snd_usb_audio_init);
652module_exit(snd_usb_audio_cleanup);
diff --git a/sound/usb/card.h b/sound/usb/card.h
new file mode 100644
index 000000000000..ed92420c1095
--- /dev/null
+++ b/sound/usb/card.h
@@ -0,0 +1,105 @@
1#ifndef __USBAUDIO_CARD_H
2#define __USBAUDIO_CARD_H
3
4#define MAX_PACKS 20
5#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
6#define MAX_URBS 8
7#define SYNC_URBS 4 /* always four urbs for sync */
8#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */
9
10struct audioformat {
11 struct list_head list;
12 u64 formats; /* ALSA format bits */
13 unsigned int channels; /* # channels */
14 unsigned int fmt_type; /* USB audio format type (1-3) */
15 unsigned int frame_size; /* samples per frame for non-audio */
16 int iface; /* interface number */
17 unsigned char altsetting; /* corresponding alternate setting */
18 unsigned char altset_idx; /* array index of altenate setting */
19 unsigned char attributes; /* corresponding attributes of cs endpoint */
20 unsigned char endpoint; /* endpoint */
21 unsigned char ep_attr; /* endpoint attributes */
22 unsigned char datainterval; /* log_2 of data packet interval */
23 unsigned int maxpacksize; /* max. packet size */
24 unsigned int rates; /* rate bitmasks */
25 unsigned int rate_min, rate_max; /* min/max rates */
26 unsigned int nr_rates; /* number of rate table entries */
27 unsigned int *rate_table; /* rate table */
28};
29
30struct snd_usb_substream;
31
32struct snd_urb_ctx {
33 struct urb *urb;
34 unsigned int buffer_size; /* size of data buffer, if data URB */
35 struct snd_usb_substream *subs;
36 int index; /* index for urb array */
37 int packets; /* number of packets per urb */
38};
39
40struct snd_urb_ops {
41 int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
42 int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
43 int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
44 int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
45};
46
47struct snd_usb_substream {
48 struct snd_usb_stream *stream;
49 struct usb_device *dev;
50 struct snd_pcm_substream *pcm_substream;
51 int direction; /* playback or capture */
52 int interface; /* current interface */
53 int endpoint; /* assigned endpoint */
54 struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
55 unsigned int cur_rate; /* current rate (for hw_params callback) */
56 unsigned int period_bytes; /* current period bytes (for hw_params callback) */
57 unsigned int altset_idx; /* USB data format: index of alternate setting */
58 unsigned int datapipe; /* the data i/o pipe */
59 unsigned int syncpipe; /* 1 - async out or adaptive in */
60 unsigned int datainterval; /* log_2 of data packet interval */
61 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
62 unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
63 unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
64 unsigned int freqmax; /* maximum sampling rate, used for buffer management */
65 unsigned int phase; /* phase accumulator */
66 unsigned int maxpacksize; /* max packet size in bytes */
67 unsigned int maxframesize; /* max packet size in frames */
68 unsigned int curpacksize; /* current packet size in bytes (for capture) */
69 unsigned int curframesize; /* current packet size in frames (for capture) */
70 unsigned int fill_max: 1; /* fill max packet size always */
71 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
72 unsigned int fmt_type; /* USB audio format type (1-3) */
73
74 unsigned int running: 1; /* running status */
75
76 unsigned int hwptr_done; /* processed byte position in the buffer */
77 unsigned int transfer_done; /* processed frames since last period update */
78 unsigned long active_mask; /* bitmask of active urbs */
79 unsigned long unlink_mask; /* bitmask of unlinked urbs */
80
81 unsigned int nurbs; /* # urbs */
82 struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */
83 struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
84 char *syncbuf; /* sync buffer for all sync URBs */
85 dma_addr_t sync_dma; /* DMA address of syncbuf */
86
87 u64 formats; /* format bitmasks (all or'ed) */
88 unsigned int num_formats; /* number of supported audio formats (list) */
89 struct list_head fmt_list; /* format list */
90 struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
91 spinlock_t lock;
92
93 struct snd_urb_ops ops; /* callbacks (must be filled at init) */
94};
95
96struct snd_usb_stream {
97 struct snd_usb_audio *chip;
98 struct snd_pcm *pcm;
99 int pcm_index;
100 unsigned int fmt_type; /* USB audio format type (1-3) */
101 struct snd_usb_substream substream[2];
102 struct list_head list;
103};
104
105#endif /* __USBAUDIO_CARD_H */
diff --git a/sound/usb/debug.h b/sound/usb/debug.h
new file mode 100644
index 000000000000..343ec2d9ee66
--- /dev/null
+++ b/sound/usb/debug.h
@@ -0,0 +1,15 @@
1#ifndef __USBAUDIO_DEBUG_H
2#define __USBAUDIO_DEBUG_H
3
4/*
5 * h/w constraints
6 */
7
8#ifdef HW_CONST_DEBUG
9#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
10#else
11#define hwc_debug(fmt, args...) /**/
12#endif
13
14#endif /* __USBAUDIO_DEBUG_H */
15
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
new file mode 100644
index 000000000000..ef07a6d0dd5f
--- /dev/null
+++ b/sound/usb/endpoint.c
@@ -0,0 +1,362 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "proc.h"
30#include "quirks.h"
31#include "endpoint.h"
32#include "urb.h"
33#include "pcm.h"
34#include "helper.h"
35#include "format.h"
36
37/*
38 * free a substream
39 */
40static void free_substream(struct snd_usb_substream *subs)
41{
42 struct list_head *p, *n;
43
44 if (!subs->num_formats)
45 return; /* not initialized */
46 list_for_each_safe(p, n, &subs->fmt_list) {
47 struct audioformat *fp = list_entry(p, struct audioformat, list);
48 kfree(fp->rate_table);
49 kfree(fp);
50 }
51 kfree(subs->rate_list.list);
52}
53
54
55/*
56 * free a usb stream instance
57 */
58static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
59{
60 free_substream(&stream->substream[0]);
61 free_substream(&stream->substream[1]);
62 list_del(&stream->list);
63 kfree(stream);
64}
65
66static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
67{
68 struct snd_usb_stream *stream = pcm->private_data;
69 if (stream) {
70 stream->pcm = NULL;
71 snd_usb_audio_stream_free(stream);
72 }
73}
74
75
76/*
77 * add this endpoint to the chip instance.
78 * if a stream with the same endpoint already exists, append to it.
79 * if not, create a new pcm stream.
80 */
81int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp)
82{
83 struct list_head *p;
84 struct snd_usb_stream *as;
85 struct snd_usb_substream *subs;
86 struct snd_pcm *pcm;
87 int err;
88
89 list_for_each(p, &chip->pcm_list) {
90 as = list_entry(p, struct snd_usb_stream, list);
91 if (as->fmt_type != fp->fmt_type)
92 continue;
93 subs = &as->substream[stream];
94 if (!subs->endpoint)
95 continue;
96 if (subs->endpoint == fp->endpoint) {
97 list_add_tail(&fp->list, &subs->fmt_list);
98 subs->num_formats++;
99 subs->formats |= fp->formats;
100 return 0;
101 }
102 }
103 /* look for an empty stream */
104 list_for_each(p, &chip->pcm_list) {
105 as = list_entry(p, struct snd_usb_stream, list);
106 if (as->fmt_type != fp->fmt_type)
107 continue;
108 subs = &as->substream[stream];
109 if (subs->endpoint)
110 continue;
111 err = snd_pcm_new_stream(as->pcm, stream, 1);
112 if (err < 0)
113 return err;
114 snd_usb_init_substream(as, stream, fp);
115 return 0;
116 }
117
118 /* create a new pcm */
119 as = kzalloc(sizeof(*as), GFP_KERNEL);
120 if (!as)
121 return -ENOMEM;
122 as->pcm_index = chip->pcm_devs;
123 as->chip = chip;
124 as->fmt_type = fp->fmt_type;
125 err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
126 stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
127 stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
128 &pcm);
129 if (err < 0) {
130 kfree(as);
131 return err;
132 }
133 as->pcm = pcm;
134 pcm->private_data = as;
135 pcm->private_free = snd_usb_audio_pcm_free;
136 pcm->info_flags = 0;
137 if (chip->pcm_devs > 0)
138 sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
139 else
140 strcpy(pcm->name, "USB Audio");
141
142 snd_usb_init_substream(as, stream, fp);
143
144 list_add(&as->list, &chip->pcm_list);
145 chip->pcm_devs++;
146
147 snd_usb_proc_pcm_format_add(as);
148
149 return 0;
150}
151
152int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
153{
154 struct usb_device *dev;
155 struct usb_interface *iface;
156 struct usb_host_interface *alts;
157 struct usb_interface_descriptor *altsd;
158 int i, altno, err, stream;
159 int format = 0, num_channels = 0;
160 struct audioformat *fp = NULL;
161 unsigned char *fmt, *csep;
162 int num, protocol;
163
164 dev = chip->dev;
165
166 /* parse the interface's altsettings */
167 iface = usb_ifnum_to_if(dev, iface_no);
168
169 num = iface->num_altsetting;
170
171 /*
172 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
173 * one misses syncpipe, and does not produce any sound.
174 */
175 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
176 num = 4;
177
178 for (i = 0; i < num; i++) {
179 alts = &iface->altsetting[i];
180 altsd = get_iface_desc(alts);
181 protocol = altsd->bInterfaceProtocol;
182 /* skip invalid one */
183 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
184 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
185 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
186 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
187 altsd->bNumEndpoints < 1 ||
188 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
189 continue;
190 /* must be isochronous */
191 if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
192 USB_ENDPOINT_XFER_ISOC)
193 continue;
194 /* check direction */
195 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
196 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
197 altno = altsd->bAlternateSetting;
198
199 if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
200 continue;
201
202 /* get audio formats */
203 switch (protocol) {
204 case UAC_VERSION_1: {
205 struct uac_as_header_descriptor_v1 *as =
206 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
207
208 if (!as) {
209 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
210 dev->devnum, iface_no, altno);
211 continue;
212 }
213
214 if (as->bLength < sizeof(*as)) {
215 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
216 dev->devnum, iface_no, altno);
217 continue;
218 }
219
220 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
221 break;
222 }
223
224 case UAC_VERSION_2: {
225 struct uac_as_header_descriptor_v2 *as =
226 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
227
228 if (!as) {
229 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
230 dev->devnum, iface_no, altno);
231 continue;
232 }
233
234 if (as->bLength < sizeof(*as)) {
235 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
236 dev->devnum, iface_no, altno);
237 continue;
238 }
239
240 num_channels = as->bNrChannels;
241 format = le32_to_cpu(as->bmFormats);
242
243 break;
244 }
245
246 default:
247 snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
248 dev->devnum, iface_no, altno, protocol);
249 continue;
250 }
251
252 /* get format type */
253 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
254 if (!fmt) {
255 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
256 dev->devnum, iface_no, altno);
257 continue;
258 }
259 if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
260 ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
261 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
262 dev->devnum, iface_no, altno);
263 continue;
264 }
265
266 /*
267 * Blue Microphones workaround: The last altsetting is identical
268 * with the previous one, except for a larger packet size, but
269 * is actually a mislabeled two-channel setting; ignore it.
270 */
271 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
272 fp && fp->altsetting == 1 && fp->channels == 1 &&
273 fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
274 protocol == UAC_VERSION_1 &&
275 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
276 fp->maxpacksize * 2)
277 continue;
278
279 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
280 /* Creamware Noah has this descriptor after the 2nd endpoint */
281 if (!csep && altsd->bNumEndpoints >= 2)
282 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
283 if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
284 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
285 " class specific endpoint descriptor\n",
286 dev->devnum, iface_no, altno);
287 csep = NULL;
288 }
289
290 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
291 if (! fp) {
292 snd_printk(KERN_ERR "cannot malloc\n");
293 return -ENOMEM;
294 }
295
296 fp->iface = iface_no;
297 fp->altsetting = altno;
298 fp->altset_idx = i;
299 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
300 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
301 fp->datainterval = snd_usb_parse_datainterval(chip, alts);
302 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
303 /* num_channels is only set for v2 interfaces */
304 fp->channels = num_channels;
305 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
306 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
307 * (fp->maxpacksize & 0x7ff);
308 fp->attributes = csep ? csep[3] : 0;
309
310 /* some quirks for attributes here */
311
312 switch (chip->usb_id) {
313 case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
314 /* Optoplay sets the sample rate attribute although
315 * it seems not supporting it in fact.
316 */
317 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
318 break;
319 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
320 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
321 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
322 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
323 /* doesn't set the sample rate attribute, but supports it */
324 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
325 break;
326 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
327 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
328 an older model 77d:223) */
329 /*
330 * plantronics headset and Griffin iMic have set adaptive-in
331 * although it's really not...
332 */
333 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
334 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
335 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
336 else
337 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
338 break;
339 }
340
341 /* ok, let's parse further... */
342 if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
343 kfree(fp->rate_table);
344 kfree(fp);
345 continue;
346 }
347
348 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
349 err = snd_usb_add_audio_endpoint(chip, stream, fp);
350 if (err < 0) {
351 kfree(fp->rate_table);
352 kfree(fp);
353 return err;
354 }
355 /* try to set the interface... */
356 usb_set_interface(chip->dev, iface_no, altno);
357 snd_usb_init_pitch(chip, iface_no, alts, fp);
358 snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max);
359 }
360 return 0;
361}
362
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
new file mode 100644
index 000000000000..64dd0db023b2
--- /dev/null
+++ b/sound/usb/endpoint.h
@@ -0,0 +1,11 @@
1#ifndef __USBAUDIO_ENDPOINT_H
2#define __USBAUDIO_ENDPOINT_H
3
4int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip,
5 int iface_no);
6
7int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip,
8 int stream,
9 struct audioformat *fp);
10
11#endif /* __USBAUDIO_ENDPOINT_H */
diff --git a/sound/usb/format.c b/sound/usb/format.c
new file mode 100644
index 000000000000..b87cf87c4e7b
--- /dev/null
+++ b/sound/usb/format.c
@@ -0,0 +1,432 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22#include <linux/usb/audio-v2.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "quirks.h"
30#include "helper.h"
31#include "debug.h"
32
33/*
34 * parse the audio format type I descriptor
35 * and returns the corresponding pcm format
36 *
37 * @dev: usb device
38 * @fp: audioformat record
39 * @format: the format tag (wFormatTag)
40 * @fmt: the format type descriptor
41 */
42static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
43 struct audioformat *fp,
44 int format, void *_fmt,
45 int protocol)
46{
47 int sample_width, sample_bytes;
48 u64 pcm_formats;
49
50 switch (protocol) {
51 case UAC_VERSION_1: {
52 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
53 sample_width = fmt->bBitResolution;
54 sample_bytes = fmt->bSubframeSize;
55 format = 1 << format;
56 break;
57 }
58
59 case UAC_VERSION_2: {
60 struct uac_format_type_i_ext_descriptor *fmt = _fmt;
61 sample_width = fmt->bBitResolution;
62 sample_bytes = fmt->bSubslotSize;
63 format <<= 1;
64 break;
65 }
66
67 default:
68 return -EINVAL;
69 }
70
71 pcm_formats = 0;
72
73 if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) {
74 /* some devices don't define this correctly... */
75 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
76 chip->dev->devnum, fp->iface, fp->altsetting);
77 format = 1 << UAC_FORMAT_TYPE_I_PCM;
78 }
79 if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) {
80 if (sample_width > sample_bytes * 8) {
81 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
82 chip->dev->devnum, fp->iface, fp->altsetting,
83 sample_width, sample_bytes);
84 }
85 /* check the format byte size */
86 switch (sample_bytes) {
87 case 1:
88 pcm_formats |= SNDRV_PCM_FMTBIT_S8;
89 break;
90 case 2:
91 if (snd_usb_is_big_endian_format(chip, fp))
92 pcm_formats |= SNDRV_PCM_FMTBIT_S16_BE; /* grrr, big endian!! */
93 else
94 pcm_formats |= SNDRV_PCM_FMTBIT_S16_LE;
95 break;
96 case 3:
97 if (snd_usb_is_big_endian_format(chip, fp))
98 pcm_formats |= SNDRV_PCM_FMTBIT_S24_3BE; /* grrr, big endian!! */
99 else
100 pcm_formats |= SNDRV_PCM_FMTBIT_S24_3LE;
101 break;
102 case 4:
103 pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE;
104 break;
105 default:
106 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
107 chip->dev->devnum, fp->iface, fp->altsetting,
108 sample_width, sample_bytes);
109 break;
110 }
111 }
112 if (format & (1 << UAC_FORMAT_TYPE_I_PCM8)) {
113 /* Dallas DS4201 workaround: it advertises U8 format, but really
114 supports S8. */
115 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
116 pcm_formats |= SNDRV_PCM_FMTBIT_S8;
117 else
118 pcm_formats |= SNDRV_PCM_FMTBIT_U8;
119 }
120 if (format & (1 << UAC_FORMAT_TYPE_I_IEEE_FLOAT)) {
121 pcm_formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
122 }
123 if (format & (1 << UAC_FORMAT_TYPE_I_ALAW)) {
124 pcm_formats |= SNDRV_PCM_FMTBIT_A_LAW;
125 }
126 if (format & (1 << UAC_FORMAT_TYPE_I_MULAW)) {
127 pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW;
128 }
129 if (format & ~0x3f) {
130 snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n",
131 chip->dev->devnum, fp->iface, fp->altsetting, format);
132 }
133 return pcm_formats;
134}
135
136
137/*
138 * parse the format descriptor and stores the possible sample rates
139 * on the audioformat table (audio class v1).
140 *
141 * @dev: usb device
142 * @fp: audioformat record
143 * @fmt: the format descriptor
144 * @offset: the start offset of descriptor pointing the rate type
145 * (7 for type I and II, 8 for type II)
146 */
147static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
148 unsigned char *fmt, int offset)
149{
150 int nr_rates = fmt[offset];
151
152 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
153 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
154 chip->dev->devnum, fp->iface, fp->altsetting);
155 return -1;
156 }
157
158 if (nr_rates) {
159 /*
160 * build the rate table and bitmap flags
161 */
162 int r, idx;
163
164 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
165 if (fp->rate_table == NULL) {
166 snd_printk(KERN_ERR "cannot malloc\n");
167 return -1;
168 }
169
170 fp->nr_rates = 0;
171 fp->rate_min = fp->rate_max = 0;
172 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
173 unsigned int rate = combine_triple(&fmt[idx]);
174 if (!rate)
175 continue;
176 /* C-Media CM6501 mislabels its 96 kHz altsetting */
177 if (rate == 48000 && nr_rates == 1 &&
178 (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
179 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
180 fp->altsetting == 5 && fp->maxpacksize == 392)
181 rate = 96000;
182 /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
183 if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
184 rate = 8000;
185
186 fp->rate_table[fp->nr_rates] = rate;
187 if (!fp->rate_min || rate < fp->rate_min)
188 fp->rate_min = rate;
189 if (!fp->rate_max || rate > fp->rate_max)
190 fp->rate_max = rate;
191 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
192 fp->nr_rates++;
193 }
194 if (!fp->nr_rates) {
195 hwc_debug("All rates were zero. Skipping format!\n");
196 return -1;
197 }
198 } else {
199 /* continuous rates */
200 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
201 fp->rate_min = combine_triple(&fmt[offset + 1]);
202 fp->rate_max = combine_triple(&fmt[offset + 4]);
203 }
204 return 0;
205}
206
207/*
208 * parse the format descriptor and stores the possible sample rates
209 * on the audioformat table (audio class v2).
210 */
211static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
212 struct audioformat *fp,
213 struct usb_host_interface *iface)
214{
215 struct usb_device *dev = chip->dev;
216 unsigned char tmp[2], *data;
217 int i, nr_rates, data_size, ret = 0;
218
219 /* get the number of sample rates first by only fetching 2 bytes */
220 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
221 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
222 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
223 tmp, sizeof(tmp), 1000);
224
225 if (ret < 0) {
226 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n");
227 goto err;
228 }
229
230 nr_rates = (tmp[1] << 8) | tmp[0];
231 data_size = 2 + 12 * nr_rates;
232 data = kzalloc(data_size, GFP_KERNEL);
233 if (!data) {
234 ret = -ENOMEM;
235 goto err;
236 }
237
238 /* now get the full information */
239 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
240 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
241 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
242 data, data_size, 1000);
243
244 if (ret < 0) {
245 snd_printk(KERN_ERR "unable to retrieve sample rate range\n");
246 ret = -EINVAL;
247 goto err_free;
248 }
249
250 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
251 if (!fp->rate_table) {
252 ret = -ENOMEM;
253 goto err_free;
254 }
255
256 fp->nr_rates = 0;
257 fp->rate_min = fp->rate_max = 0;
258
259 for (i = 0; i < nr_rates; i++) {
260 int rate = combine_quad(&data[2 + 12 * i]);
261
262 fp->rate_table[fp->nr_rates] = rate;
263 if (!fp->rate_min || rate < fp->rate_min)
264 fp->rate_min = rate;
265 if (!fp->rate_max || rate > fp->rate_max)
266 fp->rate_max = rate;
267 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
268 fp->nr_rates++;
269 }
270
271err_free:
272 kfree(data);
273err:
274 return ret;
275}
276
277/*
278 * parse the format type I and III descriptors
279 */
280static int parse_audio_format_i(struct snd_usb_audio *chip,
281 struct audioformat *fp,
282 int format, void *_fmt,
283 struct usb_host_interface *iface)
284{
285 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
286 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
287 int protocol = altsd->bInterfaceProtocol;
288 int pcm_format, ret;
289
290 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
291 /* FIXME: the format type is really IECxxx
292 * but we give normal PCM format to get the existing
293 * apps working...
294 */
295 switch (chip->usb_id) {
296
297 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
298 if (chip->setup == 0x00 &&
299 fp->altsetting == 6)
300 pcm_format = SNDRV_PCM_FORMAT_S16_BE;
301 else
302 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
303 break;
304 default:
305 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
306 }
307 fp->formats = 1uLL << pcm_format;
308 } else {
309 fp->formats = parse_audio_format_i_type(chip, fp, format,
310 fmt, protocol);
311 if (!fp->formats)
312 return -1;
313 }
314
315 /* gather possible sample rates */
316 /* audio class v1 reports possible sample rates as part of the
317 * proprietary class specific descriptor.
318 * audio class v2 uses class specific EP0 range requests for that.
319 */
320 switch (protocol) {
321 case UAC_VERSION_1:
322 fp->channels = fmt->bNrChannels;
323 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7);
324 break;
325 case UAC_VERSION_2:
326 /* fp->channels is already set in this case */
327 ret = parse_audio_format_rates_v2(chip, fp, iface);
328 break;
329 }
330
331 if (fp->channels < 1) {
332 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
333 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
334 return -1;
335 }
336
337 return ret;
338}
339
340/*
341 * parse the format type II descriptor
342 */
343static int parse_audio_format_ii(struct snd_usb_audio *chip,
344 struct audioformat *fp,
345 int format, void *_fmt,
346 struct usb_host_interface *iface)
347{
348 int brate, framesize, ret;
349 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
350 int protocol = altsd->bInterfaceProtocol;
351
352 switch (format) {
353 case UAC_FORMAT_TYPE_II_AC3:
354 /* FIXME: there is no AC3 format defined yet */
355 // fp->formats = SNDRV_PCM_FMTBIT_AC3;
356 fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */
357 break;
358 case UAC_FORMAT_TYPE_II_MPEG:
359 fp->formats = SNDRV_PCM_FMTBIT_MPEG;
360 break;
361 default:
362 snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n",
363 chip->dev->devnum, fp->iface, fp->altsetting, format);
364 fp->formats = SNDRV_PCM_FMTBIT_MPEG;
365 break;
366 }
367
368 fp->channels = 1;
369
370 switch (protocol) {
371 case UAC_VERSION_1: {
372 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
373 brate = le16_to_cpu(fmt->wMaxBitRate);
374 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
375 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
376 fp->frame_size = framesize;
377 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
378 break;
379 }
380 case UAC_VERSION_2: {
381 struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
382 brate = le16_to_cpu(fmt->wMaxBitRate);
383 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
384 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
385 fp->frame_size = framesize;
386 ret = parse_audio_format_rates_v2(chip, fp, iface);
387 break;
388 }
389 }
390
391 return ret;
392}
393
394int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
395 int format, unsigned char *fmt, int stream,
396 struct usb_host_interface *iface)
397{
398 int err;
399
400 switch (fmt[3]) {
401 case UAC_FORMAT_TYPE_I:
402 case UAC_FORMAT_TYPE_III:
403 err = parse_audio_format_i(chip, fp, format, fmt, iface);
404 break;
405 case UAC_FORMAT_TYPE_II:
406 err = parse_audio_format_ii(chip, fp, format, fmt, iface);
407 break;
408 default:
409 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
410 chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]);
411 return -1;
412 }
413 fp->fmt_type = fmt[3];
414 if (err < 0)
415 return err;
416#if 1
417 /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
418 /* extigy apparently supports sample rates other than 48k
419 * but not in ordinary way. so we enable only 48k atm.
420 */
421 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
422 chip->usb_id == USB_ID(0x041e, 0x3020) ||
423 chip->usb_id == USB_ID(0x041e, 0x3061)) {
424 if (fmt[3] == UAC_FORMAT_TYPE_I &&
425 fp->rates != SNDRV_PCM_RATE_48000 &&
426 fp->rates != SNDRV_PCM_RATE_96000)
427 return -1;
428 }
429#endif
430 return 0;
431}
432
diff --git a/sound/usb/format.h b/sound/usb/format.h
new file mode 100644
index 000000000000..8298c4e8ddfa
--- /dev/null
+++ b/sound/usb/format.h
@@ -0,0 +1,8 @@
1#ifndef __USBAUDIO_FORMAT_H
2#define __USBAUDIO_FORMAT_H
3
4int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
5 int format, unsigned char *fmt, int stream,
6 struct usb_host_interface *iface);
7
8#endif /* __USBAUDIO_FORMAT_H */
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
new file mode 100644
index 000000000000..d48d6f8f6ac9
--- /dev/null
+++ b/sound/usb/helper.c
@@ -0,0 +1,113 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21
22#include "usbaudio.h"
23#include "helper.h"
24
25/*
26 * combine bytes and get an integer value
27 */
28unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
29{
30 switch (size) {
31 case 1: return *bytes;
32 case 2: return combine_word(bytes);
33 case 3: return combine_triple(bytes);
34 case 4: return combine_quad(bytes);
35 default: return 0;
36 }
37}
38
39/*
40 * parse descriptor buffer and return the pointer starting the given
41 * descriptor type.
42 */
43void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
44{
45 u8 *p, *end, *next;
46
47 p = descstart;
48 end = p + desclen;
49 for (; p < end;) {
50 if (p[0] < 2)
51 return NULL;
52 next = p + p[0];
53 if (next > end)
54 return NULL;
55 if (p[1] == dtype && (!after || (void *)p > after)) {
56 return p;
57 }
58 p = next;
59 }
60 return NULL;
61}
62
63/*
64 * find a class-specified interface descriptor with the given subtype.
65 */
66void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
67{
68 unsigned char *p = after;
69
70 while ((p = snd_usb_find_desc(buffer, buflen, p,
71 USB_DT_CS_INTERFACE)) != NULL) {
72 if (p[0] >= 3 && p[2] == dsubtype)
73 return p;
74 }
75 return NULL;
76}
77
78/*
79 * Wrapper for usb_control_msg().
80 * Allocates a temp buffer to prevent dmaing from/to the stack.
81 */
82int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
83 __u8 requesttype, __u16 value, __u16 index, void *data,
84 __u16 size, int timeout)
85{
86 int err;
87 void *buf = NULL;
88
89 if (size > 0) {
90 buf = kmemdup(data, size, GFP_KERNEL);
91 if (!buf)
92 return -ENOMEM;
93 }
94 err = usb_control_msg(dev, pipe, request, requesttype,
95 value, index, buf, size, timeout);
96 if (size > 0) {
97 memcpy(data, buf, size);
98 kfree(buf);
99 }
100 return err;
101}
102
103unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
104 struct usb_host_interface *alts)
105{
106 if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH &&
107 get_endpoint(alts, 0)->bInterval >= 1 &&
108 get_endpoint(alts, 0)->bInterval <= 4)
109 return get_endpoint(alts, 0)->bInterval - 1;
110 else
111 return 0;
112}
113
diff --git a/sound/usb/helper.h b/sound/usb/helper.h
new file mode 100644
index 000000000000..a6b0e51b3a9a
--- /dev/null
+++ b/sound/usb/helper.h
@@ -0,0 +1,32 @@
1#ifndef __USBAUDIO_HELPER_H
2#define __USBAUDIO_HELPER_H
3
4unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
5
6void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
7void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
8
9int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
10 __u8 request, __u8 requesttype, __u16 value, __u16 index,
11 void *data, __u16 size, int timeout);
12
13unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
14 struct usb_host_interface *alts);
15
16/*
17 * retrieve usb_interface descriptor from the host interface
18 * (conditional for compatibility with the older API)
19 */
20#ifndef get_iface_desc
21#define get_iface_desc(iface) (&(iface)->desc)
22#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
23#define get_ep_desc(ep) (&(ep)->desc)
24#define get_cfg_desc(cfg) (&(cfg)->desc)
25#endif
26
27#ifndef snd_usb_get_speed
28#define snd_usb_get_speed(dev) ((dev)->speed)
29#endif
30
31
32#endif /* __USBAUDIO_HELPER_H */
diff --git a/sound/usb/usbmidi.c b/sound/usb/midi.c
index 61b2d8fd0331..8b1e4b124a9f 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/midi.c
@@ -53,7 +53,8 @@
53#include <sound/rawmidi.h> 53#include <sound/rawmidi.h>
54#include <sound/asequencer.h> 54#include <sound/asequencer.h>
55#include "usbaudio.h" 55#include "usbaudio.h"
56 56#include "midi.h"
57#include "helper.h"
57 58
58/* 59/*
59 * define this to log all USB packets 60 * define this to log all USB packets
diff --git a/sound/usb/midi.h b/sound/usb/midi.h
new file mode 100644
index 000000000000..2089ec987c66
--- /dev/null
+++ b/sound/usb/midi.h
@@ -0,0 +1,48 @@
1#ifndef __USBMIDI_H
2#define __USBMIDI_H
3
4/* maximum number of endpoints per interface */
5#define MIDI_MAX_ENDPOINTS 2
6
7/* data for QUIRK_MIDI_FIXED_ENDPOINT */
8struct snd_usb_midi_endpoint_info {
9 int8_t out_ep; /* ep number, 0 autodetect */
10 uint8_t out_interval; /* interval for interrupt endpoints */
11 int8_t in_ep;
12 uint8_t in_interval;
13 uint16_t out_cables; /* bitmask */
14 uint16_t in_cables; /* bitmask */
15};
16
17/* for QUIRK_MIDI_YAMAHA, data is NULL */
18
19/* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
20 * structure (out_cables and in_cables only) */
21
22/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
23 * structures, terminated with .ifnum = -1 */
24
25/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
26
27/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
28
29/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */
30
31/* for QUIRK_IGNORE_INTERFACE, data is NULL */
32
33/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
34
35/* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
36 * structure (out_cables and in_cables only) */
37
38/* for QUIRK_MIDI_CME, data is NULL */
39
40int snd_usbmidi_create(struct snd_card *card,
41 struct usb_interface *iface,
42 struct list_head *midi_list,
43 const struct snd_usb_audio_quirk *quirk);
44void snd_usbmidi_input_stop(struct list_head* p);
45void snd_usbmidi_input_start(struct list_head* p);
46void snd_usbmidi_disconnect(struct list_head *p);
47
48#endif /* __USBMIDI_H */
diff --git a/sound/usb/misc/Makefile b/sound/usb/misc/Makefile
new file mode 100644
index 000000000000..ccefd8158936
--- /dev/null
+++ b/sound/usb/misc/Makefile
@@ -0,0 +1,2 @@
1snd-ua101-objs := ua101.o
2obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o
diff --git a/sound/usb/ua101.c b/sound/usb/misc/ua101.c
index d700e32dee24..fb5d68fa7ff4 100644
--- a/sound/usb/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -23,7 +23,8 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include "usbaudio.h" 26#include "../usbaudio.h"
27#include "../midi.h"
27 28
28MODULE_DESCRIPTION("Edirol UA-101/1000 driver"); 29MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 30MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
diff --git a/sound/usb/usbmixer.c b/sound/usb/mixer.c
index 8e8f871b74ca..97dd17655104 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/mixer.c
@@ -33,6 +33,7 @@
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/usb/audio.h> 35#include <linux/usb/audio.h>
36#include <linux/usb/audio-v2.h>
36 37
37#include <sound/core.h> 38#include <sound/core.h>
38#include <sound/control.h> 39#include <sound/control.h>
@@ -41,60 +42,12 @@
41#include <sound/tlv.h> 42#include <sound/tlv.h>
42 43
43#include "usbaudio.h" 44#include "usbaudio.h"
44 45#include "mixer.h"
45/* 46#include "helper.h"
46 */ 47#include "mixer_quirks.h"
47
48/* ignore error from controls - for debugging */
49/* #define IGNORE_CTL_ERROR */
50
51/*
52 * Sound Blaster remote control configuration
53 *
54 * format of remote control data:
55 * Extigy: xx 00
56 * Audigy 2 NX: 06 80 xx 00 00 00
57 * Live! 24-bit: 06 80 xx yy 22 83
58 */
59static const struct rc_config {
60 u32 usb_id;
61 u8 offset;
62 u8 length;
63 u8 packet_length;
64 u8 min_packet_length; /* minimum accepted length of the URB result */
65 u8 mute_mixer_id;
66 u32 mute_code;
67} rc_configs[] = {
68 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
69 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
70 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
71 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
72};
73 48
74#define MAX_ID_ELEMS 256 49#define MAX_ID_ELEMS 256
75 50
76struct usb_mixer_interface {
77 struct snd_usb_audio *chip;
78 unsigned int ctrlif;
79 struct list_head list;
80 unsigned int ignore_ctl_error;
81 struct urb *urb;
82 /* array[MAX_ID_ELEMS], indexed by unit id */
83 struct usb_mixer_elem_info **id_elems;
84
85 /* Sound Blaster remote control stuff */
86 const struct rc_config *rc_cfg;
87 u32 rc_code;
88 wait_queue_head_t rc_waitq;
89 struct urb *rc_urb;
90 struct usb_ctrlrequest *rc_setup_packet;
91 u8 rc_buffer[6];
92
93 u8 audigy2nx_leds[3];
94 u8 xonar_u1_status;
95};
96
97
98struct usb_audio_term { 51struct usb_audio_term {
99 int id; 52 int id;
100 int type; 53 int type;
@@ -116,39 +69,6 @@ struct mixer_build {
116 const struct usbmix_selector_map *selector_map; 69 const struct usbmix_selector_map *selector_map;
117}; 70};
118 71
119#define MAX_CHANNELS 10 /* max logical channels */
120
121struct usb_mixer_elem_info {
122 struct usb_mixer_interface *mixer;
123 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
124 struct snd_ctl_elem_id *elem_id;
125 unsigned int id;
126 unsigned int control; /* CS or ICN (high byte) */
127 unsigned int cmask; /* channel mask bitmap: 0 = master */
128 int channels;
129 int val_type;
130 int min, max, res;
131 int dBmin, dBmax;
132 int cached;
133 int cache_val[MAX_CHANNELS];
134 u8 initialized;
135};
136
137
138enum {
139 USB_FEATURE_NONE = 0,
140 USB_FEATURE_MUTE = 1,
141 USB_FEATURE_VOLUME,
142 USB_FEATURE_BASS,
143 USB_FEATURE_MID,
144 USB_FEATURE_TREBLE,
145 USB_FEATURE_GEQ,
146 USB_FEATURE_AGC,
147 USB_FEATURE_DELAY,
148 USB_FEATURE_BASSBOOST,
149 USB_FEATURE_LOUDNESS
150};
151
152enum { 72enum {
153 USB_MIXER_BOOLEAN, 73 USB_MIXER_BOOLEAN,
154 USB_MIXER_INV_BOOLEAN, 74 USB_MIXER_INV_BOOLEAN,
@@ -213,7 +133,7 @@ enum {
213 * if the mixer topology is too complicated and the parsed names are 133 * if the mixer topology is too complicated and the parsed names are
214 * ambiguous, add the entries in usbmixer_maps.c. 134 * ambiguous, add the entries in usbmixer_maps.c.
215 */ 135 */
216#include "usbmixer_maps.c" 136#include "mixer_maps.c"
217 137
218static const struct usbmix_name_map * 138static const struct usbmix_name_map *
219find_map(struct mixer_build *state, int unitid, int control) 139find_map(struct mixer_build *state, int unitid, int control)
@@ -278,6 +198,7 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid,
278 198
279/* 199/*
280 * find an audio control unit with the given unit id 200 * find an audio control unit with the given unit id
201 * this doesn't return any clock related units, so they need to be handled elsewhere
281 */ 202 */
282static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit) 203static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
283{ 204{
@@ -286,7 +207,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
286 p = NULL; 207 p = NULL;
287 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, 208 while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
288 USB_DT_CS_INTERFACE)) != NULL) { 209 USB_DT_CS_INTERFACE)) != NULL) {
289 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC_EXTENSION_UNIT_V1 && p[3] == unit) 210 if (p[0] >= 4 && p[2] >= UAC_INPUT_TERMINAL && p[2] <= UAC2_EXTENSION_UNIT_V2 && p[3] == unit)
290 return p; 211 return p;
291 } 212 }
292 return NULL; 213 return NULL;
@@ -383,7 +304,7 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
383 * retrieve a mixer value 304 * retrieve a mixer value
384 */ 305 */
385 306
386static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) 307static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
387{ 308{
388 unsigned char buf[2]; 309 unsigned char buf[2];
389 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 310 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -405,6 +326,58 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
405 return -EINVAL; 326 return -EINVAL;
406} 327}
407 328
329static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
330{
331 unsigned char buf[14]; /* enough space for one range of 4 bytes */
332 unsigned char *val;
333 int ret;
334 __u8 bRequest;
335
336 bRequest = (request == UAC_GET_CUR) ?
337 UAC2_CS_CUR : UAC2_CS_RANGE;
338
339 ret = snd_usb_ctl_msg(cval->mixer->chip->dev,
340 usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
341 bRequest,
342 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
343 validx, cval->mixer->ctrlif | (cval->id << 8),
344 buf, sizeof(buf), 1000);
345
346 if (ret < 0) {
347 snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
348 request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
349 return ret;
350 }
351
352 switch (request) {
353 case UAC_GET_CUR:
354 val = buf;
355 break;
356 case UAC_GET_MIN:
357 val = buf + sizeof(__u16);
358 break;
359 case UAC_GET_MAX:
360 val = buf + sizeof(__u16) * 2;
361 break;
362 case UAC_GET_RES:
363 val = buf + sizeof(__u16) * 3;
364 break;
365 default:
366 return -EINVAL;
367 }
368
369 *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16)));
370
371 return 0;
372}
373
374static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
375{
376 return (cval->mixer->protocol == UAC_VERSION_1) ?
377 get_ctl_value_v1(cval, request, validx, value_ret) :
378 get_ctl_value_v2(cval, request, validx, value_ret);
379}
380
408static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value) 381static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
409{ 382{
410 return get_ctl_value(cval, UAC_GET_CUR, validx, value); 383 return get_ctl_value(cval, UAC_GET_CUR, validx, value);
@@ -429,8 +402,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
429 err = get_cur_mix_raw(cval, channel, value); 402 err = get_cur_mix_raw(cval, channel, value);
430 if (err < 0) { 403 if (err < 0) {
431 if (!cval->mixer->ignore_ctl_error) 404 if (!cval->mixer->ignore_ctl_error)
432 snd_printd(KERN_ERR "cannot get current value for " 405 snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n",
433 "control %d ch %d: err = %d\n",
434 cval->control, channel, err); 406 cval->control, channel, err);
435 return err; 407 return err;
436 } 408 }
@@ -444,11 +416,26 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
444 * set a mixer value 416 * set a mixer value
445 */ 417 */
446 418
447static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int value_set) 419int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
420 int request, int validx, int value_set)
448{ 421{
449 unsigned char buf[2]; 422 unsigned char buf[2];
450 int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; 423 int val_len, timeout = 10;
451 int timeout = 10; 424
425 if (cval->mixer->protocol == UAC_VERSION_1) {
426 val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
427 } else { /* UAC_VERSION_2 */
428 /* audio class v2 controls are always 2 bytes in size */
429 val_len = sizeof(__u16);
430
431 /* FIXME */
432 if (request != UAC_SET_CUR) {
433 snd_printdd(KERN_WARNING "RANGE setting not yet supported\n");
434 return -EINVAL;
435 }
436
437 request = UAC2_CS_CUR;
438 }
452 439
453 value_set = convert_bytes_value(cval, value_set); 440 value_set = convert_bytes_value(cval, value_set);
454 buf[0] = value_set & 0xff; 441 buf[0] = value_set & 0xff;
@@ -468,14 +455,14 @@ static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
468 455
469static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) 456static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
470{ 457{
471 return set_ctl_value(cval, UAC_SET_CUR, validx, value); 458 return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
472} 459}
473 460
474static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, 461static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
475 int index, int value) 462 int index, int value)
476{ 463{
477 int err; 464 int err;
478 err = set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel, 465 err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
479 value); 466 value);
480 if (err < 0) 467 if (err < 0)
481 return err; 468 return err;
@@ -644,46 +631,65 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
644 */ 631 */
645static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) 632static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
646{ 633{
647 unsigned char *p1; 634 void *p1;
648 635
649 memset(term, 0, sizeof(*term)); 636 memset(term, 0, sizeof(*term));
650 while ((p1 = find_audio_control_unit(state, id)) != NULL) { 637 while ((p1 = find_audio_control_unit(state, id)) != NULL) {
638 unsigned char *hdr = p1;
651 term->id = id; 639 term->id = id;
652 switch (p1[2]) { 640 switch (hdr[2]) {
653 case UAC_INPUT_TERMINAL: 641 case UAC_INPUT_TERMINAL:
654 term->type = combine_word(p1 + 4); 642 if (state->mixer->protocol == UAC_VERSION_1) {
655 term->channels = p1[7]; 643 struct uac_input_terminal_descriptor *d = p1;
656 term->chconfig = combine_word(p1 + 8); 644 term->type = le16_to_cpu(d->wTerminalType);
657 term->name = p1[11]; 645 term->channels = d->bNrChannels;
646 term->chconfig = le16_to_cpu(d->wChannelConfig);
647 term->name = d->iTerminal;
648 } else { /* UAC_VERSION_2 */
649 struct uac2_input_terminal_descriptor *d = p1;
650 term->type = le16_to_cpu(d->wTerminalType);
651 term->channels = d->bNrChannels;
652 term->chconfig = le32_to_cpu(d->bmChannelConfig);
653 term->name = d->iTerminal;
654 }
658 return 0; 655 return 0;
659 case UAC_FEATURE_UNIT: 656 case UAC_FEATURE_UNIT: {
660 id = p1[4]; 657 /* the header is the same for v1 and v2 */
658 struct uac_feature_unit_descriptor *d = p1;
659 id = d->bSourceID;
661 break; /* continue to parse */ 660 break; /* continue to parse */
662 case UAC_MIXER_UNIT: 661 }
663 term->type = p1[2] << 16; /* virtual type */ 662 case UAC_MIXER_UNIT: {
664 term->channels = p1[5 + p1[4]]; 663 struct uac_mixer_unit_descriptor *d = p1;
665 term->chconfig = combine_word(p1 + 6 + p1[4]); 664 term->type = d->bDescriptorSubtype << 16; /* virtual type */
666 term->name = p1[p1[0] - 1]; 665 term->channels = uac_mixer_unit_bNrChannels(d);
666 term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->protocol);
667 term->name = uac_mixer_unit_iMixer(d);
667 return 0; 668 return 0;
668 case UAC_SELECTOR_UNIT: 669 }
670 case UAC_SELECTOR_UNIT: {
671 struct uac_selector_unit_descriptor *d = p1;
669 /* call recursively to retrieve the channel info */ 672 /* call recursively to retrieve the channel info */
670 if (check_input_term(state, p1[5], term) < 0) 673 if (check_input_term(state, d->baSourceID[0], term) < 0)
671 return -ENODEV; 674 return -ENODEV;
672 term->type = p1[2] << 16; /* virtual type */ 675 term->type = d->bDescriptorSubtype << 16; /* virtual type */
673 term->id = id; 676 term->id = id;
674 term->name = p1[9 + p1[0] - 1]; 677 term->name = uac_selector_unit_iSelector(d);
675 return 0; 678 return 0;
679 }
676 case UAC_PROCESSING_UNIT_V1: 680 case UAC_PROCESSING_UNIT_V1:
677 case UAC_EXTENSION_UNIT_V1: 681 case UAC_EXTENSION_UNIT_V1: {
678 if (p1[6] == 1) { 682 struct uac_processing_unit_descriptor *d = p1;
679 id = p1[7]; 683 if (d->bNrInPins) {
684 id = d->baSourceID[0];
680 break; /* continue to parse */ 685 break; /* continue to parse */
681 } 686 }
682 term->type = p1[2] << 16; /* virtual type */ 687 term->type = d->bDescriptorSubtype << 16; /* virtual type */
683 term->channels = p1[7 + p1[6]]; 688 term->channels = uac_processing_unit_bNrChannels(d);
684 term->chconfig = combine_word(p1 + 8 + p1[6]); 689 term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol);
685 term->name = p1[12 + p1[6] + p1[11 + p1[6]]]; 690 term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol);
686 return 0; 691 return 0;
692 }
687 default: 693 default:
688 return -ENODEV; 694 return -ENODEV;
689 } 695 }
@@ -764,7 +770,8 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
764 int last_valid_res = cval->res; 770 int last_valid_res = cval->res;
765 771
766 while (cval->res > 1) { 772 while (cval->res > 1) {
767 if (set_ctl_value(cval, UAC_SET_RES, (cval->control << 8) | minchn, cval->res / 2) < 0) 773 if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
774 (cval->control << 8) | minchn, cval->res / 2) < 0)
768 break; 775 break;
769 cval->res /= 2; 776 cval->res /= 2;
770 } 777 }
@@ -929,6 +936,15 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
929 .put = mixer_ctl_feature_put, 936 .put = mixer_ctl_feature_put,
930}; 937};
931 938
939/* the read-only variant */
940static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
941 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
942 .name = "", /* will be filled later manually */
943 .info = mixer_ctl_feature_info,
944 .get = mixer_ctl_feature_get,
945 .put = NULL,
946};
947
932 948
933/* 949/*
934 * build a feature control 950 * build a feature control
@@ -939,20 +955,22 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
939 return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); 955 return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
940} 956}
941 957
942static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, 958static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
943 unsigned int ctl_mask, int control, 959 unsigned int ctl_mask, int control,
944 struct usb_audio_term *iterm, int unitid) 960 struct usb_audio_term *iterm, int unitid,
961 int read_only)
945{ 962{
963 struct uac_feature_unit_descriptor *desc = raw_desc;
946 unsigned int len = 0; 964 unsigned int len = 0;
947 int mapped_name = 0; 965 int mapped_name = 0;
948 int nameid = desc[desc[0] - 1]; 966 int nameid = uac_feature_unit_iFeature(desc);
949 struct snd_kcontrol *kctl; 967 struct snd_kcontrol *kctl;
950 struct usb_mixer_elem_info *cval; 968 struct usb_mixer_elem_info *cval;
951 const struct usbmix_name_map *map; 969 const struct usbmix_name_map *map;
952 970
953 control++; /* change from zero-based to 1-based value */ 971 control++; /* change from zero-based to 1-based value */
954 972
955 if (control == USB_FEATURE_GEQ) { 973 if (control == UAC_GRAPHIC_EQUALIZER_CONTROL) {
956 /* FIXME: not supported yet */ 974 /* FIXME: not supported yet */
957 return; 975 return;
958 } 976 }
@@ -984,7 +1002,11 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
984 /* get min/max values */ 1002 /* get min/max values */
985 get_min_max(cval, 0); 1003 get_min_max(cval, 0);
986 1004
987 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); 1005 if (read_only)
1006 kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
1007 else
1008 kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
1009
988 if (! kctl) { 1010 if (! kctl) {
989 snd_printk(KERN_ERR "cannot malloc kcontrol\n"); 1011 snd_printk(KERN_ERR "cannot malloc kcontrol\n");
990 kfree(cval); 1012 kfree(cval);
@@ -999,8 +1021,8 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
999 kctl->id.name, sizeof(kctl->id.name)); 1021 kctl->id.name, sizeof(kctl->id.name));
1000 1022
1001 switch (control) { 1023 switch (control) {
1002 case USB_FEATURE_MUTE: 1024 case UAC_MUTE_CONTROL:
1003 case USB_FEATURE_VOLUME: 1025 case UAC_VOLUME_CONTROL:
1004 /* determine the control name. the rule is: 1026 /* determine the control name. the rule is:
1005 * - if a name id is given in descriptor, use it. 1027 * - if a name id is given in descriptor, use it.
1006 * - if the connected input can be determined, then use the name 1028 * - if the connected input can be determined, then use the name
@@ -1027,9 +1049,9 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
1027 len = append_ctl_name(kctl, " Playback"); 1049 len = append_ctl_name(kctl, " Playback");
1028 } 1050 }
1029 } 1051 }
1030 append_ctl_name(kctl, control == USB_FEATURE_MUTE ? 1052 append_ctl_name(kctl, control == UAC_MUTE_CONTROL ?
1031 " Switch" : " Volume"); 1053 " Switch" : " Volume");
1032 if (control == USB_FEATURE_VOLUME) { 1054 if (control == UAC_VOLUME_CONTROL) {
1033 kctl->tlv.c = mixer_vol_tlv; 1055 kctl->tlv.c = mixer_vol_tlv;
1034 kctl->vd[0].access |= 1056 kctl->vd[0].access |=
1035 SNDRV_CTL_ELEM_ACCESS_TLV_READ | 1057 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
@@ -1094,49 +1116,92 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1094 struct usb_audio_term iterm; 1116 struct usb_audio_term iterm;
1095 unsigned int master_bits, first_ch_bits; 1117 unsigned int master_bits, first_ch_bits;
1096 int err, csize; 1118 int err, csize;
1097 struct uac_feature_unit_descriptor *ftr = _ftr; 1119 struct uac_feature_unit_descriptor *hdr = _ftr;
1120 __u8 *bmaControls;
1098 1121
1099 if (ftr->bLength < 7 || ! (csize = ftr->bControlSize) || ftr->bLength < 7 + csize) { 1122 if (state->mixer->protocol == UAC_VERSION_1) {
1123 csize = hdr->bControlSize;
1124 channels = (hdr->bLength - 7) / csize - 1;
1125 bmaControls = hdr->bmaControls;
1126 } else {
1127 struct uac2_feature_unit_descriptor *ftr = _ftr;
1128 csize = 4;
1129 channels = (hdr->bLength - 6) / 4;
1130 bmaControls = ftr->bmaControls;
1131 }
1132
1133 if (hdr->bLength < 7 || !csize || hdr->bLength < 7 + csize) {
1100 snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid); 1134 snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid);
1101 return -EINVAL; 1135 return -EINVAL;
1102 } 1136 }
1103 1137
1104 /* parse the source unit */ 1138 /* parse the source unit */
1105 if ((err = parse_audio_unit(state, ftr->bSourceID)) < 0) 1139 if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0)
1106 return err; 1140 return err;
1107 1141
1108 /* determine the input source type and name */ 1142 /* determine the input source type and name */
1109 if (check_input_term(state, ftr->bSourceID, &iterm) < 0) 1143 if (check_input_term(state, hdr->bSourceID, &iterm) < 0)
1110 return -EINVAL; 1144 return -EINVAL;
1111 1145
1112 channels = (ftr->bLength - 7) / csize - 1; 1146 master_bits = snd_usb_combine_bytes(bmaControls, csize);
1113
1114 master_bits = snd_usb_combine_bytes(ftr->controls, csize);
1115 /* master configuration quirks */ 1147 /* master configuration quirks */
1116 switch (state->chip->usb_id) { 1148 switch (state->chip->usb_id) {
1117 case USB_ID(0x08bb, 0x2702): 1149 case USB_ID(0x08bb, 0x2702):
1118 snd_printk(KERN_INFO 1150 snd_printk(KERN_INFO
1119 "usbmixer: master volume quirk for PCM2702 chip\n"); 1151 "usbmixer: master volume quirk for PCM2702 chip\n");
1120 /* disable non-functional volume control */ 1152 /* disable non-functional volume control */
1121 master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1)); 1153 master_bits &= ~UAC_FU_VOLUME;
1122 break; 1154 break;
1123 } 1155 }
1124 if (channels > 0) 1156 if (channels > 0)
1125 first_ch_bits = snd_usb_combine_bytes(ftr->controls + csize, csize); 1157 first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
1126 else 1158 else
1127 first_ch_bits = 0; 1159 first_ch_bits = 0;
1128 /* check all control types */ 1160
1129 for (i = 0; i < 10; i++) { 1161 if (state->mixer->protocol == UAC_VERSION_1) {
1130 unsigned int ch_bits = 0; 1162 /* check all control types */
1131 for (j = 0; j < channels; j++) { 1163 for (i = 0; i < 10; i++) {
1132 unsigned int mask = snd_usb_combine_bytes(ftr->controls + csize * (j+1), csize); 1164 unsigned int ch_bits = 0;
1133 if (mask & (1 << i)) 1165 for (j = 0; j < channels; j++) {
1134 ch_bits |= (1 << j); 1166 unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
1167 if (mask & (1 << i))
1168 ch_bits |= (1 << j);
1169 }
1170 /* audio class v1 controls are never read-only */
1171 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1172 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0);
1173 if (master_bits & (1 << i))
1174 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
1175 }
1176 } else { /* UAC_VERSION_2 */
1177 for (i = 0; i < 30/2; i++) {
1178 /* From the USB Audio spec v2.0:
1179 bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
1180 each containing a set of bit pairs. If a Control is present,
1181 it must be Host readable. If a certain Control is not
1182 present then the bit pair must be set to 0b00.
1183 If a Control is present but read-only, the bit pair must be
1184 set to 0b01. If a Control is also Host programmable, the bit
1185 pair must be set to 0b11. The value 0b10 is not allowed. */
1186 unsigned int ch_bits = 0;
1187 unsigned int ch_read_only = 0;
1188
1189 for (j = 0; j < channels; j++) {
1190 unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
1191 if (mask & (1 << (i * 2))) {
1192 ch_bits |= (1 << j);
1193 if (~mask & (1 << ((i * 2) + 1)))
1194 ch_read_only |= (1 << j);
1195 }
1196 }
1197
1198 /* FIXME: the whole unit is read-only if any of the channels is marked read-only */
1199 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1200 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, !!ch_read_only);
1201 if (master_bits & (1 << i * 2))
1202 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
1203 ~master_bits & (1 << ((i * 2) + 1)));
1135 } 1204 }
1136 if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
1137 build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid);
1138 if (master_bits & (1 << i))
1139 build_feature_ctl(state, _ftr, 0, i, &iterm, unitid);
1140 } 1205 }
1141 1206
1142 return 0; 1207 return 0;
@@ -1154,13 +1219,13 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
1154 * input channel number (zero based) is given in control field instead. 1219 * input channel number (zero based) is given in control field instead.
1155 */ 1220 */
1156 1221
1157static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc, 1222static void build_mixer_unit_ctl(struct mixer_build *state,
1223 struct uac_mixer_unit_descriptor *desc,
1158 int in_pin, int in_ch, int unitid, 1224 int in_pin, int in_ch, int unitid,
1159 struct usb_audio_term *iterm) 1225 struct usb_audio_term *iterm)
1160{ 1226{
1161 struct usb_mixer_elem_info *cval; 1227 struct usb_mixer_elem_info *cval;
1162 unsigned int input_pins = desc[4]; 1228 unsigned int num_outs = uac_mixer_unit_bNrChannels(desc);
1163 unsigned int num_outs = desc[5 + input_pins];
1164 unsigned int i, len; 1229 unsigned int i, len;
1165 struct snd_kcontrol *kctl; 1230 struct snd_kcontrol *kctl;
1166 const struct usbmix_name_map *map; 1231 const struct usbmix_name_map *map;
@@ -1178,7 +1243,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1178 cval->control = in_ch + 1; /* based on 1 */ 1243 cval->control = in_ch + 1; /* based on 1 */
1179 cval->val_type = USB_MIXER_S16; 1244 cval->val_type = USB_MIXER_S16;
1180 for (i = 0; i < num_outs; i++) { 1245 for (i = 0; i < num_outs; i++) {
1181 if (check_matrix_bitmap(desc + 9 + input_pins, in_ch, i, num_outs)) { 1246 if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) {
1182 cval->cmask |= (1 << i); 1247 cval->cmask |= (1 << i);
1183 cval->channels++; 1248 cval->channels++;
1184 } 1249 }
@@ -1211,18 +1276,19 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1211/* 1276/*
1212 * parse a mixer unit 1277 * parse a mixer unit
1213 */ 1278 */
1214static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1279static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
1215{ 1280{
1281 struct uac_mixer_unit_descriptor *desc = raw_desc;
1216 struct usb_audio_term iterm; 1282 struct usb_audio_term iterm;
1217 int input_pins, num_ins, num_outs; 1283 int input_pins, num_ins, num_outs;
1218 int pin, ich, err; 1284 int pin, ich, err;
1219 1285
1220 if (desc[0] < 11 || ! (input_pins = desc[4]) || ! (num_outs = desc[5 + input_pins])) { 1286 if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
1221 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid); 1287 snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
1222 return -EINVAL; 1288 return -EINVAL;
1223 } 1289 }
1224 /* no bmControls field (e.g. Maya44) -> ignore */ 1290 /* no bmControls field (e.g. Maya44) -> ignore */
1225 if (desc[0] <= 10 + input_pins) { 1291 if (desc->bLength <= 10 + input_pins) {
1226 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid); 1292 snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
1227 return 0; 1293 return 0;
1228 } 1294 }
@@ -1230,10 +1296,10 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigne
1230 num_ins = 0; 1296 num_ins = 0;
1231 ich = 0; 1297 ich = 0;
1232 for (pin = 0; pin < input_pins; pin++) { 1298 for (pin = 0; pin < input_pins; pin++) {
1233 err = parse_audio_unit(state, desc[5 + pin]); 1299 err = parse_audio_unit(state, desc->baSourceID[pin]);
1234 if (err < 0) 1300 if (err < 0)
1235 return err; 1301 return err;
1236 err = check_input_term(state, desc[5 + pin], &iterm); 1302 err = check_input_term(state, desc->baSourceID[pin], &iterm);
1237 if (err < 0) 1303 if (err < 0)
1238 return err; 1304 return err;
1239 num_ins += iterm.channels; 1305 num_ins += iterm.channels;
@@ -1241,7 +1307,7 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigne
1241 int och, ich_has_controls = 0; 1307 int och, ich_has_controls = 0;
1242 1308
1243 for (och = 0; och < num_outs; ++och) { 1309 for (och = 0; och < num_outs; ++och) {
1244 if (check_matrix_bitmap(desc + 9 + input_pins, 1310 if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol),
1245 ich, och, num_outs)) { 1311 ich, och, num_outs)) {
1246 ich_has_controls = 1; 1312 ich_has_controls = 1;
1247 break; 1313 break;
@@ -1377,8 +1443,8 @@ static struct procunit_info procunits[] = {
1377 * predefined data for extension units 1443 * predefined data for extension units
1378 */ 1444 */
1379static struct procunit_value_info clock_rate_xu_info[] = { 1445static struct procunit_value_info clock_rate_xu_info[] = {
1380 { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 }, 1446 { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
1381 { 0 } 1447 { 0 }
1382}; 1448};
1383static struct procunit_value_info clock_source_xu_info[] = { 1449static struct procunit_value_info clock_source_xu_info[] = {
1384 { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN }, 1450 { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
@@ -1402,9 +1468,10 @@ static struct procunit_info extunits[] = {
1402/* 1468/*
1403 * build a processing/extension unit 1469 * build a processing/extension unit
1404 */ 1470 */
1405static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned char *dsc, struct procunit_info *list, char *name) 1471static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
1406{ 1472{
1407 int num_ins = dsc[6]; 1473 struct uac_processing_unit_descriptor *desc = raw_desc;
1474 int num_ins = desc->bNrInPins;
1408 struct usb_mixer_elem_info *cval; 1475 struct usb_mixer_elem_info *cval;
1409 struct snd_kcontrol *kctl; 1476 struct snd_kcontrol *kctl;
1410 int i, err, nameid, type, len; 1477 int i, err, nameid, type, len;
@@ -1419,17 +1486,18 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1419 0, NULL, default_value_info 1486 0, NULL, default_value_info
1420 }; 1487 };
1421 1488
1422 if (dsc[0] < 13 || dsc[0] < 13 + num_ins || dsc[0] < num_ins + dsc[11 + num_ins]) { 1489 if (desc->bLength < 13 || desc->bLength < 13 + num_ins ||
1490 desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) {
1423 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid); 1491 snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid);
1424 return -EINVAL; 1492 return -EINVAL;
1425 } 1493 }
1426 1494
1427 for (i = 0; i < num_ins; i++) { 1495 for (i = 0; i < num_ins; i++) {
1428 if ((err = parse_audio_unit(state, dsc[7 + i])) < 0) 1496 if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
1429 return err; 1497 return err;
1430 } 1498 }
1431 1499
1432 type = combine_word(&dsc[4]); 1500 type = le16_to_cpu(desc->wProcessType);
1433 for (info = list; info && info->type; info++) 1501 for (info = list; info && info->type; info++)
1434 if (info->type == type) 1502 if (info->type == type)
1435 break; 1503 break;
@@ -1437,8 +1505,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1437 info = &default_info; 1505 info = &default_info;
1438 1506
1439 for (valinfo = info->values; valinfo->control; valinfo++) { 1507 for (valinfo = info->values; valinfo->control; valinfo++) {
1440 /* FIXME: bitmap might be longer than 8bit */ 1508 __u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
1441 if (! (dsc[12 + num_ins] & (1 << (valinfo->control - 1)))) 1509
1510 if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
1442 continue; 1511 continue;
1443 map = find_map(state, unitid, valinfo->control); 1512 map = find_map(state, unitid, valinfo->control);
1444 if (check_ignored_ctl(map)) 1513 if (check_ignored_ctl(map))
@@ -1456,9 +1525,10 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1456 1525
1457 /* get min/max values */ 1526 /* get min/max values */
1458 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) { 1527 if (type == USB_PROC_UPDOWN && cval->control == USB_PROC_UPDOWN_MODE_SEL) {
1528 __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol);
1459 /* FIXME: hard-coded */ 1529 /* FIXME: hard-coded */
1460 cval->min = 1; 1530 cval->min = 1;
1461 cval->max = dsc[15]; 1531 cval->max = control_spec[0];
1462 cval->res = 1; 1532 cval->res = 1;
1463 cval->initialized = 1; 1533 cval->initialized = 1;
1464 } else { 1534 } else {
@@ -1488,7 +1558,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1488 else if (info->name) 1558 else if (info->name)
1489 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); 1559 strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
1490 else { 1560 else {
1491 nameid = dsc[12 + num_ins + dsc[11 + num_ins]]; 1561 nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
1492 len = 0; 1562 len = 0;
1493 if (nameid) 1563 if (nameid)
1494 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); 1564 len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
@@ -1507,14 +1577,16 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1507} 1577}
1508 1578
1509 1579
1510static int parse_audio_processing_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1580static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
1511{ 1581{
1512 return build_audio_procunit(state, unitid, desc, procunits, "Processing Unit"); 1582 return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
1513} 1583}
1514 1584
1515static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1585static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
1516{ 1586{
1517 return build_audio_procunit(state, unitid, desc, extunits, "Extension Unit"); 1587 /* Note that we parse extension units with processing unit descriptors.
1588 * That's ok as the layout is the same */
1589 return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
1518} 1590}
1519 1591
1520 1592
@@ -1616,9 +1688,9 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
1616/* 1688/*
1617 * parse a selector unit 1689 * parse a selector unit
1618 */ 1690 */
1619static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsigned char *desc) 1691static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
1620{ 1692{
1621 unsigned int num_ins = desc[4]; 1693 struct uac_selector_unit_descriptor *desc = raw_desc;
1622 unsigned int i, nameid, len; 1694 unsigned int i, nameid, len;
1623 int err; 1695 int err;
1624 struct usb_mixer_elem_info *cval; 1696 struct usb_mixer_elem_info *cval;
@@ -1626,17 +1698,17 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1626 const struct usbmix_name_map *map; 1698 const struct usbmix_name_map *map;
1627 char **namelist; 1699 char **namelist;
1628 1700
1629 if (! num_ins || desc[0] < 5 + num_ins) { 1701 if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
1630 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid); 1702 snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
1631 return -EINVAL; 1703 return -EINVAL;
1632 } 1704 }
1633 1705
1634 for (i = 0; i < num_ins; i++) { 1706 for (i = 0; i < desc->bNrInPins; i++) {
1635 if ((err = parse_audio_unit(state, desc[5 + i])) < 0) 1707 if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
1636 return err; 1708 return err;
1637 } 1709 }
1638 1710
1639 if (num_ins == 1) /* only one ? nonsense! */ 1711 if (desc->bNrInPins == 1) /* only one ? nonsense! */
1640 return 0; 1712 return 0;
1641 1713
1642 map = find_map(state, unitid, 0); 1714 map = find_map(state, unitid, 0);
@@ -1653,18 +1725,18 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1653 cval->val_type = USB_MIXER_U8; 1725 cval->val_type = USB_MIXER_U8;
1654 cval->channels = 1; 1726 cval->channels = 1;
1655 cval->min = 1; 1727 cval->min = 1;
1656 cval->max = num_ins; 1728 cval->max = desc->bNrInPins;
1657 cval->res = 1; 1729 cval->res = 1;
1658 cval->initialized = 1; 1730 cval->initialized = 1;
1659 1731
1660 namelist = kmalloc(sizeof(char *) * num_ins, GFP_KERNEL); 1732 namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
1661 if (! namelist) { 1733 if (! namelist) {
1662 snd_printk(KERN_ERR "cannot malloc\n"); 1734 snd_printk(KERN_ERR "cannot malloc\n");
1663 kfree(cval); 1735 kfree(cval);
1664 return -ENOMEM; 1736 return -ENOMEM;
1665 } 1737 }
1666#define MAX_ITEM_NAME_LEN 64 1738#define MAX_ITEM_NAME_LEN 64
1667 for (i = 0; i < num_ins; i++) { 1739 for (i = 0; i < desc->bNrInPins; i++) {
1668 struct usb_audio_term iterm; 1740 struct usb_audio_term iterm;
1669 len = 0; 1741 len = 0;
1670 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); 1742 namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
@@ -1678,7 +1750,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1678 } 1750 }
1679 len = check_mapped_selector_name(state, unitid, i, namelist[i], 1751 len = check_mapped_selector_name(state, unitid, i, namelist[i],
1680 MAX_ITEM_NAME_LEN); 1752 MAX_ITEM_NAME_LEN);
1681 if (! len && check_input_term(state, desc[5 + i], &iterm) >= 0) 1753 if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
1682 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); 1754 len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
1683 if (! len) 1755 if (! len)
1684 sprintf(namelist[i], "Input %d", i); 1756 sprintf(namelist[i], "Input %d", i);
@@ -1694,7 +1766,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1694 kctl->private_value = (unsigned long)namelist; 1766 kctl->private_value = (unsigned long)namelist;
1695 kctl->private_free = usb_mixer_selector_elem_free; 1767 kctl->private_free = usb_mixer_selector_elem_free;
1696 1768
1697 nameid = desc[desc[0] - 1]; 1769 nameid = uac_selector_unit_iSelector(desc);
1698 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); 1770 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
1699 if (len) 1771 if (len)
1700 ; 1772 ;
@@ -1713,7 +1785,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1713 } 1785 }
1714 1786
1715 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", 1787 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
1716 cval->id, kctl->id.name, num_ins); 1788 cval->id, kctl->id.name, desc->bNrInPins);
1717 if ((err = add_control_to_empty(state, kctl)) < 0) 1789 if ((err = add_control_to_empty(state, kctl)) < 0)
1718 return err; 1790 return err;
1719 1791
@@ -1748,9 +1820,17 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
1748 case UAC_FEATURE_UNIT: 1820 case UAC_FEATURE_UNIT:
1749 return parse_audio_feature_unit(state, unitid, p1); 1821 return parse_audio_feature_unit(state, unitid, p1);
1750 case UAC_PROCESSING_UNIT_V1: 1822 case UAC_PROCESSING_UNIT_V1:
1751 return parse_audio_processing_unit(state, unitid, p1); 1823 /* UAC2_EFFECT_UNIT has the same value */
1824 if (state->mixer->protocol == UAC_VERSION_1)
1825 return parse_audio_processing_unit(state, unitid, p1);
1826 else
1827 return 0; /* FIXME - effect units not implemented yet */
1752 case UAC_EXTENSION_UNIT_V1: 1828 case UAC_EXTENSION_UNIT_V1:
1753 return parse_audio_extension_unit(state, unitid, p1); 1829 /* UAC2_PROCESSING_UNIT_V2 has the same value */
1830 if (state->mixer->protocol == UAC_VERSION_1)
1831 return parse_audio_extension_unit(state, unitid, p1);
1832 else /* UAC_VERSION_2 */
1833 return parse_audio_processing_unit(state, unitid, p1);
1754 default: 1834 default:
1755 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); 1835 snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
1756 return -EINVAL; 1836 return -EINVAL;
@@ -1783,11 +1863,11 @@ static int snd_usb_mixer_dev_free(struct snd_device *device)
1783 */ 1863 */
1784static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) 1864static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1785{ 1865{
1786 struct uac_output_terminal_descriptor_v1 *desc;
1787 struct mixer_build state; 1866 struct mixer_build state;
1788 int err; 1867 int err;
1789 const struct usbmix_ctl_map *map; 1868 const struct usbmix_ctl_map *map;
1790 struct usb_host_interface *hostif; 1869 struct usb_host_interface *hostif;
1870 void *p;
1791 1871
1792 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0]; 1872 hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
1793 memset(&state, 0, sizeof(state)); 1873 memset(&state, 0, sizeof(state));
@@ -1806,23 +1886,39 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
1806 } 1886 }
1807 } 1887 }
1808 1888
1809 desc = NULL; 1889 p = NULL;
1810 while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, UAC_OUTPUT_TERMINAL)) != NULL) { 1890 while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) {
1811 if (desc->bLength < 9) 1891 if (mixer->protocol == UAC_VERSION_1) {
1812 continue; /* invalid descriptor? */ 1892 struct uac_output_terminal_descriptor_v1 *desc = p;
1813 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */ 1893
1814 state.oterm.id = desc->bTerminalID; 1894 if (desc->bLength < sizeof(*desc))
1815 state.oterm.type = le16_to_cpu(desc->wTerminalType); 1895 continue; /* invalid descriptor? */
1816 state.oterm.name = desc->iTerminal; 1896 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1817 err = parse_audio_unit(&state, desc->bSourceID); 1897 state.oterm.id = desc->bTerminalID;
1818 if (err < 0) 1898 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1819 return err; 1899 state.oterm.name = desc->iTerminal;
1900 err = parse_audio_unit(&state, desc->bSourceID);
1901 if (err < 0)
1902 return err;
1903 } else { /* UAC_VERSION_2 */
1904 struct uac2_output_terminal_descriptor *desc = p;
1905
1906 if (desc->bLength < sizeof(*desc))
1907 continue; /* invalid descriptor? */
1908 set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
1909 state.oterm.id = desc->bTerminalID;
1910 state.oterm.type = le16_to_cpu(desc->wTerminalType);
1911 state.oterm.name = desc->iTerminal;
1912 err = parse_audio_unit(&state, desc->bSourceID);
1913 if (err < 0)
1914 return err;
1915 }
1820 } 1916 }
1917
1821 return 0; 1918 return 0;
1822} 1919}
1823 1920
1824static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, 1921void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
1825 int unitid)
1826{ 1922{
1827 struct usb_mixer_elem_info *info; 1923 struct usb_mixer_elem_info *info;
1828 1924
@@ -1871,54 +1967,98 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
1871 } 1967 }
1872} 1968}
1873 1969
1874static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer, 1970static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
1875 int unitid) 1971 int attribute, int value, int index)
1876{ 1972{
1877 if (!mixer->rc_cfg) 1973 struct usb_mixer_elem_info *info;
1974 __u8 unitid = (index >> 8) & 0xff;
1975 __u8 control = (value >> 8) & 0xff;
1976 __u8 channel = value & 0xff;
1977
1978 if (channel >= MAX_CHANNELS) {
1979 snd_printk(KERN_DEBUG "%s(): bogus channel number %d\n",
1980 __func__, channel);
1878 return; 1981 return;
1879 /* unit ids specific to Extigy/Audigy 2 NX: */ 1982 }
1880 switch (unitid) { 1983
1881 case 0: /* remote control */ 1984 for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) {
1882 mixer->rc_urb->dev = mixer->chip->dev; 1985 if (info->control != control)
1883 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC); 1986 continue;
1884 break; 1987
1885 case 4: /* digital in jack */ 1988 switch (attribute) {
1886 case 7: /* line in jacks */ 1989 case UAC2_CS_CUR:
1887 case 19: /* speaker out jacks */ 1990 /* invalidate cache, so the value is read from the device */
1888 case 20: /* headphones out jack */ 1991 if (channel)
1889 break; 1992 info->cached &= ~(1 << channel);
1890 /* live24ext: 4 = line-in jack */ 1993 else /* master channel */
1891 case 3: /* hp-out jack (may actuate Mute) */ 1994 info->cached = 0;
1892 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || 1995
1893 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) 1996 snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
1894 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id); 1997 info->elem_id);
1895 break; 1998 break;
1896 default: 1999
1897 snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid); 2000 case UAC2_CS_RANGE:
1898 break; 2001 /* TODO */
2002 break;
2003
2004 case UAC2_CS_MEM:
2005 /* TODO */
2006 break;
2007
2008 default:
2009 snd_printk(KERN_DEBUG "unknown attribute %d in interrupt\n",
2010 attribute);
2011 break;
2012 } /* switch */
1899 } 2013 }
1900} 2014}
1901 2015
1902static void snd_usb_mixer_status_complete(struct urb *urb) 2016static void snd_usb_mixer_interrupt(struct urb *urb)
1903{ 2017{
1904 struct usb_mixer_interface *mixer = urb->context; 2018 struct usb_mixer_interface *mixer = urb->context;
2019 int len = urb->actual_length;
2020
2021 if (urb->status != 0)
2022 goto requeue;
1905 2023
1906 if (urb->status == 0) { 2024 if (mixer->protocol == UAC_VERSION_1) {
1907 u8 *buf = urb->transfer_buffer; 2025 struct uac1_status_word *status;
1908 int i;
1909 2026
1910 for (i = urb->actual_length; i >= 2; buf += 2, i -= 2) { 2027 for (status = urb->transfer_buffer;
2028 len >= sizeof(*status);
2029 len -= sizeof(*status), status++) {
1911 snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n", 2030 snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n",
1912 buf[0], buf[1]); 2031 status->bStatusType,
2032 status->bOriginator);
2033
1913 /* ignore any notifications not from the control interface */ 2034 /* ignore any notifications not from the control interface */
1914 if ((buf[0] & 0x0f) != 0) 2035 if ((status->bStatusType & UAC1_STATUS_TYPE_ORIG_MASK) !=
2036 UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF)
1915 continue; 2037 continue;
1916 if (!(buf[0] & 0x40)) 2038
1917 snd_usb_mixer_notify_id(mixer, buf[1]); 2039 if (status->bStatusType & UAC1_STATUS_TYPE_MEM_CHANGED)
2040 snd_usb_mixer_rc_memory_change(mixer, status->bOriginator);
1918 else 2041 else
1919 snd_usb_mixer_memory_change(mixer, buf[1]); 2042 snd_usb_mixer_notify_id(mixer, status->bOriginator);
2043 }
2044 } else { /* UAC_VERSION_2 */
2045 struct uac2_interrupt_data_msg *msg;
2046
2047 for (msg = urb->transfer_buffer;
2048 len >= sizeof(*msg);
2049 len -= sizeof(*msg), msg++) {
2050 /* drop vendor specific and endpoint requests */
2051 if ((msg->bInfo & UAC2_INTERRUPT_DATA_MSG_VENDOR) ||
2052 (msg->bInfo & UAC2_INTERRUPT_DATA_MSG_EP))
2053 continue;
2054
2055 snd_usb_mixer_interrupt_v2(mixer, msg->bAttribute,
2056 le16_to_cpu(msg->wValue),
2057 le16_to_cpu(msg->wIndex));
1920 } 2058 }
1921 } 2059 }
2060
2061requeue:
1922 if (urb->status != -ENOENT && urb->status != -ECONNRESET) { 2062 if (urb->status != -ENOENT && urb->status != -ECONNRESET) {
1923 urb->dev = mixer->chip->dev; 2063 urb->dev = mixer->chip->dev;
1924 usb_submit_urb(urb, GFP_ATOMIC); 2064 usb_submit_urb(urb, GFP_ATOMIC);
@@ -1955,301 +2095,11 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
1955 usb_fill_int_urb(mixer->urb, mixer->chip->dev, 2095 usb_fill_int_urb(mixer->urb, mixer->chip->dev,
1956 usb_rcvintpipe(mixer->chip->dev, epnum), 2096 usb_rcvintpipe(mixer->chip->dev, epnum),
1957 transfer_buffer, buffer_length, 2097 transfer_buffer, buffer_length,
1958 snd_usb_mixer_status_complete, mixer, ep->bInterval); 2098 snd_usb_mixer_interrupt, mixer, ep->bInterval);
1959 usb_submit_urb(mixer->urb, GFP_KERNEL); 2099 usb_submit_urb(mixer->urb, GFP_KERNEL);
1960 return 0; 2100 return 0;
1961} 2101}
1962 2102
1963static void snd_usb_soundblaster_remote_complete(struct urb *urb)
1964{
1965 struct usb_mixer_interface *mixer = urb->context;
1966 const struct rc_config *rc = mixer->rc_cfg;
1967 u32 code;
1968
1969 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
1970 return;
1971
1972 code = mixer->rc_buffer[rc->offset];
1973 if (rc->length == 2)
1974 code |= mixer->rc_buffer[rc->offset + 1] << 8;
1975
1976 /* the Mute button actually changes the mixer control */
1977 if (code == rc->mute_code)
1978 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
1979 mixer->rc_code = code;
1980 wmb();
1981 wake_up(&mixer->rc_waitq);
1982}
1983
1984static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
1985 long count, loff_t *offset)
1986{
1987 struct usb_mixer_interface *mixer = hw->private_data;
1988 int err;
1989 u32 rc_code;
1990
1991 if (count != 1 && count != 4)
1992 return -EINVAL;
1993 err = wait_event_interruptible(mixer->rc_waitq,
1994 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
1995 if (err == 0) {
1996 if (count == 1)
1997 err = put_user(rc_code, buf);
1998 else
1999 err = put_user(rc_code, (u32 __user *)buf);
2000 }
2001 return err < 0 ? err : count;
2002}
2003
2004static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
2005 poll_table *wait)
2006{
2007 struct usb_mixer_interface *mixer = hw->private_data;
2008
2009 poll_wait(file, &mixer->rc_waitq, wait);
2010 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
2011}
2012
2013static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
2014{
2015 struct snd_hwdep *hwdep;
2016 int err, len, i;
2017
2018 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
2019 if (rc_configs[i].usb_id == mixer->chip->usb_id)
2020 break;
2021 if (i >= ARRAY_SIZE(rc_configs))
2022 return 0;
2023 mixer->rc_cfg = &rc_configs[i];
2024
2025 len = mixer->rc_cfg->packet_length;
2026
2027 init_waitqueue_head(&mixer->rc_waitq);
2028 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
2029 if (err < 0)
2030 return err;
2031 snprintf(hwdep->name, sizeof(hwdep->name),
2032 "%s remote control", mixer->chip->card->shortname);
2033 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
2034 hwdep->private_data = mixer;
2035 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
2036 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
2037 hwdep->exclusive = 1;
2038
2039 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
2040 if (!mixer->rc_urb)
2041 return -ENOMEM;
2042 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
2043 if (!mixer->rc_setup_packet) {
2044 usb_free_urb(mixer->rc_urb);
2045 mixer->rc_urb = NULL;
2046 return -ENOMEM;
2047 }
2048 mixer->rc_setup_packet->bRequestType =
2049 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
2050 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
2051 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
2052 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
2053 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
2054 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
2055 usb_rcvctrlpipe(mixer->chip->dev, 0),
2056 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
2057 snd_usb_soundblaster_remote_complete, mixer);
2058 return 0;
2059}
2060
2061#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
2062
2063static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2064{
2065 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2066 int index = kcontrol->private_value;
2067
2068 ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
2069 return 0;
2070}
2071
2072static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
2073{
2074 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2075 int index = kcontrol->private_value;
2076 int value = ucontrol->value.integer.value[0];
2077 int err, changed;
2078
2079 if (value > 1)
2080 return -EINVAL;
2081 changed = value != mixer->audigy2nx_leds[index];
2082 err = snd_usb_ctl_msg(mixer->chip->dev,
2083 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
2084 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
2085 value, index + 2, NULL, 0, 100);
2086 if (err < 0)
2087 return err;
2088 mixer->audigy2nx_leds[index] = value;
2089 return changed;
2090}
2091
2092static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
2093 {
2094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2095 .name = "CMSS LED Switch",
2096 .info = snd_audigy2nx_led_info,
2097 .get = snd_audigy2nx_led_get,
2098 .put = snd_audigy2nx_led_put,
2099 .private_value = 0,
2100 },
2101 {
2102 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2103 .name = "Power LED Switch",
2104 .info = snd_audigy2nx_led_info,
2105 .get = snd_audigy2nx_led_get,
2106 .put = snd_audigy2nx_led_put,
2107 .private_value = 1,
2108 },
2109 {
2110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2111 .name = "Dolby Digital LED Switch",
2112 .info = snd_audigy2nx_led_info,
2113 .get = snd_audigy2nx_led_get,
2114 .put = snd_audigy2nx_led_put,
2115 .private_value = 2,
2116 },
2117};
2118
2119static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
2120{
2121 int i, err;
2122
2123 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
2124 if (i > 1 && /* Live24ext has 2 LEDs only */
2125 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2126 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
2127 break;
2128 err = snd_ctl_add(mixer->chip->card,
2129 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
2130 if (err < 0)
2131 return err;
2132 }
2133 mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
2134 return 0;
2135}
2136
2137static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
2138 struct snd_info_buffer *buffer)
2139{
2140 static const struct sb_jack {
2141 int unitid;
2142 const char *name;
2143 } jacks_audigy2nx[] = {
2144 {4, "dig in "},
2145 {7, "line in"},
2146 {19, "spk out"},
2147 {20, "hph out"},
2148 {-1, NULL}
2149 }, jacks_live24ext[] = {
2150 {4, "line in"}, /* &1=Line, &2=Mic*/
2151 {3, "hph out"}, /* headphones */
2152 {0, "RC "}, /* last command, 6 bytes see rc_config above */
2153 {-1, NULL}
2154 };
2155 const struct sb_jack *jacks;
2156 struct usb_mixer_interface *mixer = entry->private_data;
2157 int i, err;
2158 u8 buf[3];
2159
2160 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
2161 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
2162 jacks = jacks_audigy2nx;
2163 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2164 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
2165 jacks = jacks_live24ext;
2166 else
2167 return;
2168
2169 for (i = 0; jacks[i].name; ++i) {
2170 snd_iprintf(buffer, "%s: ", jacks[i].name);
2171 err = snd_usb_ctl_msg(mixer->chip->dev,
2172 usb_rcvctrlpipe(mixer->chip->dev, 0),
2173 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
2174 USB_RECIP_INTERFACE, 0,
2175 jacks[i].unitid << 8, buf, 3, 100);
2176 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
2177 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
2178 else
2179 snd_iprintf(buffer, "?\n");
2180 }
2181}
2182
2183static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
2184 struct snd_ctl_elem_value *ucontrol)
2185{
2186 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2187
2188 ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
2189 return 0;
2190}
2191
2192static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
2193 struct snd_ctl_elem_value *ucontrol)
2194{
2195 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
2196 u8 old_status, new_status;
2197 int err, changed;
2198
2199 old_status = mixer->xonar_u1_status;
2200 if (ucontrol->value.integer.value[0])
2201 new_status = old_status | 0x02;
2202 else
2203 new_status = old_status & ~0x02;
2204 changed = new_status != old_status;
2205 err = snd_usb_ctl_msg(mixer->chip->dev,
2206 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
2207 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
2208 50, 0, &new_status, 1, 100);
2209 if (err < 0)
2210 return err;
2211 mixer->xonar_u1_status = new_status;
2212 return changed;
2213}
2214
2215static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
2216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2217 .name = "Digital Playback Switch",
2218 .info = snd_ctl_boolean_mono_info,
2219 .get = snd_xonar_u1_switch_get,
2220 .put = snd_xonar_u1_switch_put,
2221};
2222
2223static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
2224{
2225 int err;
2226
2227 err = snd_ctl_add(mixer->chip->card,
2228 snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
2229 if (err < 0)
2230 return err;
2231 mixer->xonar_u1_status = 0x05;
2232 return 0;
2233}
2234
2235void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
2236 unsigned char samplerate_id)
2237{
2238 struct usb_mixer_interface *mixer;
2239 struct usb_mixer_elem_info *cval;
2240 int unitid = 12; /* SamleRate ExtensionUnit ID */
2241
2242 list_for_each_entry(mixer, &chip->mixer_list, list) {
2243 cval = mixer->id_elems[unitid];
2244 if (cval) {
2245 set_cur_ctl_value(cval, cval->control << 8,
2246 samplerate_id);
2247 snd_usb_mixer_notify_id(mixer, unitid);
2248 }
2249 break;
2250 }
2251}
2252
2253int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, 2103int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2254 int ignore_error) 2104 int ignore_error)
2255{ 2105{
@@ -2259,7 +2109,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2259 struct usb_mixer_interface *mixer; 2109 struct usb_mixer_interface *mixer;
2260 struct snd_info_entry *entry; 2110 struct snd_info_entry *entry;
2261 struct usb_host_interface *host_iface; 2111 struct usb_host_interface *host_iface;
2262 int err, protocol; 2112 int err;
2263 2113
2264 strcpy(chip->card->mixername, "USB Mixer"); 2114 strcpy(chip->card->mixername, "USB Mixer");
2265 2115
@@ -2277,38 +2127,13 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
2277 } 2127 }
2278 2128
2279 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; 2129 host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
2280 protocol = host_iface->desc.bInterfaceProtocol; 2130 mixer->protocol = get_iface_desc(host_iface)->bInterfaceProtocol;
2281
2282 /* FIXME! */
2283 if (protocol != UAC_VERSION_1) {
2284 snd_printk(KERN_WARNING "mixer interface protocol 0x%02x not yet supported\n",
2285 protocol);
2286 return 0;
2287 }
2288 2131
2289 if ((err = snd_usb_mixer_controls(mixer)) < 0 || 2132 if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
2290 (err = snd_usb_mixer_status_create(mixer)) < 0) 2133 (err = snd_usb_mixer_status_create(mixer)) < 0)
2291 goto _error; 2134 goto _error;
2292 2135
2293 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0) 2136 snd_usb_mixer_apply_create_quirk(mixer);
2294 goto _error;
2295
2296 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
2297 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
2298 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
2299 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
2300 goto _error;
2301 if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
2302 snd_info_set_text_ops(entry, mixer,
2303 snd_audigy2nx_proc_read);
2304 }
2305
2306 if (mixer->chip->usb_id == USB_ID(0x0b05, 0x1739) ||
2307 mixer->chip->usb_id == USB_ID(0x0b05, 0x1743)) {
2308 err = snd_xonar_u1_controls_create(mixer);
2309 if (err < 0)
2310 goto _error;
2311 }
2312 2137
2313 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops); 2138 err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
2314 if (err < 0) 2139 if (err < 0)
@@ -2329,7 +2154,7 @@ _error:
2329void snd_usb_mixer_disconnect(struct list_head *p) 2154void snd_usb_mixer_disconnect(struct list_head *p)
2330{ 2155{
2331 struct usb_mixer_interface *mixer; 2156 struct usb_mixer_interface *mixer;
2332 2157
2333 mixer = list_entry(p, struct usb_mixer_interface, list); 2158 mixer = list_entry(p, struct usb_mixer_interface, list);
2334 usb_kill_urb(mixer->urb); 2159 usb_kill_urb(mixer->urb);
2335 usb_kill_urb(mixer->rc_urb); 2160 usb_kill_urb(mixer->rc_urb);
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
new file mode 100644
index 000000000000..130123854a6c
--- /dev/null
+++ b/sound/usb/mixer.h
@@ -0,0 +1,55 @@
1#ifndef __USBMIXER_H
2#define __USBMIXER_H
3
4struct usb_mixer_interface {
5 struct snd_usb_audio *chip;
6 unsigned int ctrlif;
7 struct list_head list;
8 unsigned int ignore_ctl_error;
9 struct urb *urb;
10 /* array[MAX_ID_ELEMS], indexed by unit id */
11 struct usb_mixer_elem_info **id_elems;
12
13 /* the usb audio specification version this interface complies to */
14 int protocol;
15
16 /* Sound Blaster remote control stuff */
17 const struct rc_config *rc_cfg;
18 u32 rc_code;
19 wait_queue_head_t rc_waitq;
20 struct urb *rc_urb;
21 struct usb_ctrlrequest *rc_setup_packet;
22 u8 rc_buffer[6];
23
24 u8 audigy2nx_leds[3];
25 u8 xonar_u1_status;
26};
27
28#define MAX_CHANNELS 10 /* max logical channels */
29
30struct usb_mixer_elem_info {
31 struct usb_mixer_interface *mixer;
32 struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
33 struct snd_ctl_elem_id *elem_id;
34 unsigned int id;
35 unsigned int control; /* CS or ICN (high byte) */
36 unsigned int cmask; /* channel mask bitmap: 0 = master */
37 int channels;
38 int val_type;
39 int min, max, res;
40 int dBmin, dBmax;
41 int cached;
42 int cache_val[MAX_CHANNELS];
43 u8 initialized;
44};
45
46int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
47 int ignore_error);
48void snd_usb_mixer_disconnect(struct list_head *p);
49
50void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
51
52int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
53 int request, int validx, int value_set);
54
55#endif /* __USBMIXER_H */
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/mixer_maps.c
index 79e903a60862..d93fc89beba8 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -85,8 +85,8 @@ static struct usbmix_name_map extigy_map[] = {
85 /* 16: MU (w/o controls) */ 85 /* 16: MU (w/o controls) */
86 { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */ 86 { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */
87 { 17, "Channel Routing", 2 }, /* PU: mode select */ 87 { 17, "Channel Routing", 2 }, /* PU: mode select */
88 { 18, "Tone Control - Bass", USB_FEATURE_BASS }, /* FU */ 88 { 18, "Tone Control - Bass", UAC_BASS_CONTROL }, /* FU */
89 { 18, "Tone Control - Treble", USB_FEATURE_TREBLE }, /* FU */ 89 { 18, "Tone Control - Treble", UAC_TREBLE_CONTROL }, /* FU */
90 { 18, "Master Playback" }, /* FU; others */ 90 { 18, "Master Playback" }, /* FU; others */
91 /* 19: OT speaker */ 91 /* 19: OT speaker */
92 /* 20: OT headphone */ 92 /* 20: OT headphone */
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
new file mode 100644
index 000000000000..e7df1e5e3f2e
--- /dev/null
+++ b/sound/usb/mixer_quirks.c
@@ -0,0 +1,412 @@
1/*
2 * USB Audio Driver for ALSA
3 *
4 * Quirks and vendor-specific extensions for mixer interfaces
5 *
6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7 *
8 * Many codes borrowed from audio.c by
9 * Alan Cox (alan@lxorguk.ukuu.org.uk)
10 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <linux/usb.h>
31#include <linux/usb/audio.h>
32
33#include <sound/core.h>
34#include <sound/control.h>
35#include <sound/hwdep.h>
36#include <sound/info.h>
37
38#include "usbaudio.h"
39#include "mixer.h"
40#include "mixer_quirks.h"
41#include "helper.h"
42
43/*
44 * Sound Blaster remote control configuration
45 *
46 * format of remote control data:
47 * Extigy: xx 00
48 * Audigy 2 NX: 06 80 xx 00 00 00
49 * Live! 24-bit: 06 80 xx yy 22 83
50 */
51static const struct rc_config {
52 u32 usb_id;
53 u8 offset;
54 u8 length;
55 u8 packet_length;
56 u8 min_packet_length; /* minimum accepted length of the URB result */
57 u8 mute_mixer_id;
58 u32 mute_code;
59} rc_configs[] = {
60 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
63 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
64};
65
66static void snd_usb_soundblaster_remote_complete(struct urb *urb)
67{
68 struct usb_mixer_interface *mixer = urb->context;
69 const struct rc_config *rc = mixer->rc_cfg;
70 u32 code;
71
72 if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
73 return;
74
75 code = mixer->rc_buffer[rc->offset];
76 if (rc->length == 2)
77 code |= mixer->rc_buffer[rc->offset + 1] << 8;
78
79 /* the Mute button actually changes the mixer control */
80 if (code == rc->mute_code)
81 snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
82 mixer->rc_code = code;
83 wmb();
84 wake_up(&mixer->rc_waitq);
85}
86
87static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
88 long count, loff_t *offset)
89{
90 struct usb_mixer_interface *mixer = hw->private_data;
91 int err;
92 u32 rc_code;
93
94 if (count != 1 && count != 4)
95 return -EINVAL;
96 err = wait_event_interruptible(mixer->rc_waitq,
97 (rc_code = xchg(&mixer->rc_code, 0)) != 0);
98 if (err == 0) {
99 if (count == 1)
100 err = put_user(rc_code, buf);
101 else
102 err = put_user(rc_code, (u32 __user *)buf);
103 }
104 return err < 0 ? err : count;
105}
106
107static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
108 poll_table *wait)
109{
110 struct usb_mixer_interface *mixer = hw->private_data;
111
112 poll_wait(file, &mixer->rc_waitq, wait);
113 return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
114}
115
116static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
117{
118 struct snd_hwdep *hwdep;
119 int err, len, i;
120
121 for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
122 if (rc_configs[i].usb_id == mixer->chip->usb_id)
123 break;
124 if (i >= ARRAY_SIZE(rc_configs))
125 return 0;
126 mixer->rc_cfg = &rc_configs[i];
127
128 len = mixer->rc_cfg->packet_length;
129
130 init_waitqueue_head(&mixer->rc_waitq);
131 err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
132 if (err < 0)
133 return err;
134 snprintf(hwdep->name, sizeof(hwdep->name),
135 "%s remote control", mixer->chip->card->shortname);
136 hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
137 hwdep->private_data = mixer;
138 hwdep->ops.read = snd_usb_sbrc_hwdep_read;
139 hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
140 hwdep->exclusive = 1;
141
142 mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
143 if (!mixer->rc_urb)
144 return -ENOMEM;
145 mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
146 if (!mixer->rc_setup_packet) {
147 usb_free_urb(mixer->rc_urb);
148 mixer->rc_urb = NULL;
149 return -ENOMEM;
150 }
151 mixer->rc_setup_packet->bRequestType =
152 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
153 mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
154 mixer->rc_setup_packet->wValue = cpu_to_le16(0);
155 mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
156 mixer->rc_setup_packet->wLength = cpu_to_le16(len);
157 usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
158 usb_rcvctrlpipe(mixer->chip->dev, 0),
159 (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
160 snd_usb_soundblaster_remote_complete, mixer);
161 return 0;
162}
163
164#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
165
166static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
167{
168 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
169 int index = kcontrol->private_value;
170
171 ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
172 return 0;
173}
174
175static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
176{
177 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
178 int index = kcontrol->private_value;
179 int value = ucontrol->value.integer.value[0];
180 int err, changed;
181
182 if (value > 1)
183 return -EINVAL;
184 changed = value != mixer->audigy2nx_leds[index];
185 err = snd_usb_ctl_msg(mixer->chip->dev,
186 usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
187 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
188 value, index + 2, NULL, 0, 100);
189 if (err < 0)
190 return err;
191 mixer->audigy2nx_leds[index] = value;
192 return changed;
193}
194
195static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
196 {
197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
198 .name = "CMSS LED Switch",
199 .info = snd_audigy2nx_led_info,
200 .get = snd_audigy2nx_led_get,
201 .put = snd_audigy2nx_led_put,
202 .private_value = 0,
203 },
204 {
205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
206 .name = "Power LED Switch",
207 .info = snd_audigy2nx_led_info,
208 .get = snd_audigy2nx_led_get,
209 .put = snd_audigy2nx_led_put,
210 .private_value = 1,
211 },
212 {
213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
214 .name = "Dolby Digital LED Switch",
215 .info = snd_audigy2nx_led_info,
216 .get = snd_audigy2nx_led_get,
217 .put = snd_audigy2nx_led_put,
218 .private_value = 2,
219 },
220};
221
222static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
223{
224 int i, err;
225
226 for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
227 if (i > 1 && /* Live24ext has 2 LEDs only */
228 (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
229 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
230 break;
231 err = snd_ctl_add(mixer->chip->card,
232 snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
233 if (err < 0)
234 return err;
235 }
236 mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
237 return 0;
238}
239
240static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
241 struct snd_info_buffer *buffer)
242{
243 static const struct sb_jack {
244 int unitid;
245 const char *name;
246 } jacks_audigy2nx[] = {
247 {4, "dig in "},
248 {7, "line in"},
249 {19, "spk out"},
250 {20, "hph out"},
251 {-1, NULL}
252 }, jacks_live24ext[] = {
253 {4, "line in"}, /* &1=Line, &2=Mic*/
254 {3, "hph out"}, /* headphones */
255 {0, "RC "}, /* last command, 6 bytes see rc_config above */
256 {-1, NULL}
257 };
258 const struct sb_jack *jacks;
259 struct usb_mixer_interface *mixer = entry->private_data;
260 int i, err;
261 u8 buf[3];
262
263 snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
264 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
265 jacks = jacks_audigy2nx;
266 else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
267 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
268 jacks = jacks_live24ext;
269 else
270 return;
271
272 for (i = 0; jacks[i].name; ++i) {
273 snd_iprintf(buffer, "%s: ", jacks[i].name);
274 err = snd_usb_ctl_msg(mixer->chip->dev,
275 usb_rcvctrlpipe(mixer->chip->dev, 0),
276 UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
277 USB_RECIP_INTERFACE, 0,
278 jacks[i].unitid << 8, buf, 3, 100);
279 if (err == 3 && (buf[0] == 3 || buf[0] == 6))
280 snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
281 else
282 snd_iprintf(buffer, "?\n");
283 }
284}
285
286static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
287 struct snd_ctl_elem_value *ucontrol)
288{
289 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
290
291 ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
292 return 0;
293}
294
295static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
296 struct snd_ctl_elem_value *ucontrol)
297{
298 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
299 u8 old_status, new_status;
300 int err, changed;
301
302 old_status = mixer->xonar_u1_status;
303 if (ucontrol->value.integer.value[0])
304 new_status = old_status | 0x02;
305 else
306 new_status = old_status & ~0x02;
307 changed = new_status != old_status;
308 err = snd_usb_ctl_msg(mixer->chip->dev,
309 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
310 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
311 50, 0, &new_status, 1, 100);
312 if (err < 0)
313 return err;
314 mixer->xonar_u1_status = new_status;
315 return changed;
316}
317
318static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
320 .name = "Digital Playback Switch",
321 .info = snd_ctl_boolean_mono_info,
322 .get = snd_xonar_u1_switch_get,
323 .put = snd_xonar_u1_switch_put,
324};
325
326static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
327{
328 int err;
329
330 err = snd_ctl_add(mixer->chip->card,
331 snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
332 if (err < 0)
333 return err;
334 mixer->xonar_u1_status = 0x05;
335 return 0;
336}
337
338void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
339 unsigned char samplerate_id)
340{
341 struct usb_mixer_interface *mixer;
342 struct usb_mixer_elem_info *cval;
343 int unitid = 12; /* SamleRate ExtensionUnit ID */
344
345 list_for_each_entry(mixer, &chip->mixer_list, list) {
346 cval = mixer->id_elems[unitid];
347 if (cval) {
348 snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
349 cval->control << 8,
350 samplerate_id);
351 snd_usb_mixer_notify_id(mixer, unitid);
352 }
353 break;
354 }
355}
356
357int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
358{
359 int err;
360 struct snd_info_entry *entry;
361
362 if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
363 return err;
364
365 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
366 mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
367 mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) {
368 if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
369 return err;
370 if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
371 snd_info_set_text_ops(entry, mixer,
372 snd_audigy2nx_proc_read);
373 }
374
375 if (mixer->chip->usb_id == USB_ID(0x0b05, 0x1739) ||
376 mixer->chip->usb_id == USB_ID(0x0b05, 0x1743)) {
377 err = snd_xonar_u1_controls_create(mixer);
378 if (err < 0)
379 return err;
380 }
381
382 return 0;
383}
384
385void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
386 int unitid)
387{
388 if (!mixer->rc_cfg)
389 return;
390 /* unit ids specific to Extigy/Audigy 2 NX: */
391 switch (unitid) {
392 case 0: /* remote control */
393 mixer->rc_urb->dev = mixer->chip->dev;
394 usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
395 break;
396 case 4: /* digital in jack */
397 case 7: /* line in jacks */
398 case 19: /* speaker out jacks */
399 case 20: /* headphones out jack */
400 break;
401 /* live24ext: 4 = line-in jack */
402 case 3: /* hp-out jack (may actuate Mute) */
403 if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
404 mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
405 snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
406 break;
407 default:
408 snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
409 break;
410 }
411}
412
diff --git a/sound/usb/mixer_quirks.h b/sound/usb/mixer_quirks.h
new file mode 100644
index 000000000000..bdbfab093816
--- /dev/null
+++ b/sound/usb/mixer_quirks.h
@@ -0,0 +1,13 @@
1#ifndef SND_USB_MIXER_QUIRKS_H
2#define SND_USB_MIXER_QUIRKS_H
3
4int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer);
5
6void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
7 unsigned char samplerate_id);
8
9void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
10 int unitid);
11
12#endif /* SND_USB_MIXER_QUIRKS_H */
13
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
new file mode 100644
index 000000000000..2bf0d77d1768
--- /dev/null
+++ b/sound/usb/pcm.c
@@ -0,0 +1,935 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/usb.h>
20#include <linux/usb/audio.h>
21#include <linux/usb/audio-v2.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26
27#include "usbaudio.h"
28#include "card.h"
29#include "quirks.h"
30#include "debug.h"
31#include "urb.h"
32#include "helper.h"
33#include "pcm.h"
34
35/*
36 * return the current pcm pointer. just based on the hwptr_done value.
37 */
38static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
39{
40 struct snd_usb_substream *subs;
41 unsigned int hwptr_done;
42
43 subs = (struct snd_usb_substream *)substream->runtime->private_data;
44 spin_lock(&subs->lock);
45 hwptr_done = subs->hwptr_done;
46 spin_unlock(&subs->lock);
47 return hwptr_done / (substream->runtime->frame_bits >> 3);
48}
49
50/*
51 * find a matching audio format
52 */
53static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
54 unsigned int rate, unsigned int channels)
55{
56 struct list_head *p;
57 struct audioformat *found = NULL;
58 int cur_attr = 0, attr;
59
60 list_for_each(p, &subs->fmt_list) {
61 struct audioformat *fp;
62 fp = list_entry(p, struct audioformat, list);
63 if (!(fp->formats & (1uLL << format)))
64 continue;
65 if (fp->channels != channels)
66 continue;
67 if (rate < fp->rate_min || rate > fp->rate_max)
68 continue;
69 if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
70 unsigned int i;
71 for (i = 0; i < fp->nr_rates; i++)
72 if (fp->rate_table[i] == rate)
73 break;
74 if (i >= fp->nr_rates)
75 continue;
76 }
77 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
78 if (! found) {
79 found = fp;
80 cur_attr = attr;
81 continue;
82 }
83 /* avoid async out and adaptive in if the other method
84 * supports the same format.
85 * this is a workaround for the case like
86 * M-audio audiophile USB.
87 */
88 if (attr != cur_attr) {
89 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
90 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
91 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
92 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
93 continue;
94 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
95 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
96 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
97 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
98 found = fp;
99 cur_attr = attr;
100 continue;
101 }
102 }
103 /* find the format with the largest max. packet size */
104 if (fp->maxpacksize > found->maxpacksize) {
105 found = fp;
106 cur_attr = attr;
107 }
108 }
109 return found;
110}
111
112static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
113 struct usb_host_interface *alts,
114 struct audioformat *fmt)
115{
116 struct usb_device *dev = chip->dev;
117 unsigned int ep;
118 unsigned char data[1];
119 int err;
120
121 ep = get_endpoint(alts, 0)->bEndpointAddress;
122
123 /* if endpoint doesn't have pitch control, bail out */
124 if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
125 return 0;
126
127 data[0] = 1;
128 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
129 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
130 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,
131 data, sizeof(data), 1000)) < 0) {
132 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
133 dev->devnum, iface, ep);
134 return err;
135 }
136
137 return 0;
138}
139
140/*
141 * initialize the picth control and sample rate
142 */
143int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
144 struct usb_host_interface *alts,
145 struct audioformat *fmt)
146{
147 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
148
149 switch (altsd->bInterfaceProtocol) {
150 case UAC_VERSION_1:
151 return init_pitch_v1(chip, iface, alts, fmt);
152
153 case UAC_VERSION_2:
154 /* not implemented yet */
155 return 0;
156 }
157
158 return -EINVAL;
159}
160
161static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
162 struct usb_host_interface *alts,
163 struct audioformat *fmt, int rate)
164{
165 struct usb_device *dev = chip->dev;
166 unsigned int ep;
167 unsigned char data[3];
168 int err, crate;
169
170 ep = get_endpoint(alts, 0)->bEndpointAddress;
171 /* if endpoint doesn't have sampling rate control, bail out */
172 if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) {
173 snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n",
174 dev->devnum, iface, fmt->altsetting);
175 return 0;
176 }
177
178 data[0] = rate;
179 data[1] = rate >> 8;
180 data[2] = rate >> 16;
181 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
182 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
183 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
184 data, sizeof(data), 1000)) < 0) {
185 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
186 dev->devnum, iface, fmt->altsetting, rate, ep);
187 return err;
188 }
189 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
190 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
191 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
192 data, sizeof(data), 1000)) < 0) {
193 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
194 dev->devnum, iface, fmt->altsetting, ep);
195 return 0; /* some devices don't support reading */
196 }
197 crate = data[0] | (data[1] << 8) | (data[2] << 16);
198 if (crate != rate) {
199 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
200 // runtime->rate = crate;
201 }
202
203 return 0;
204}
205
206static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
207 struct usb_host_interface *alts,
208 struct audioformat *fmt, int rate)
209{
210 struct usb_device *dev = chip->dev;
211 unsigned char data[4];
212 int err, crate;
213
214 data[0] = rate;
215 data[1] = rate >> 8;
216 data[2] = rate >> 16;
217 data[3] = rate >> 24;
218 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
219 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
220 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
221 data, sizeof(data), 1000)) < 0) {
222 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
223 dev->devnum, iface, fmt->altsetting, rate);
224 return err;
225 }
226 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
227 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
228 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8,
229 data, sizeof(data), 1000)) < 0) {
230 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
231 dev->devnum, iface, fmt->altsetting);
232 return err;
233 }
234 crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
235 if (crate != rate)
236 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
237
238 return 0;
239}
240
241int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
242 struct usb_host_interface *alts,
243 struct audioformat *fmt, int rate)
244{
245 struct usb_interface_descriptor *altsd = get_iface_desc(alts);
246
247 switch (altsd->bInterfaceProtocol) {
248 case UAC_VERSION_1:
249 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
250
251 case UAC_VERSION_2:
252 return set_sample_rate_v2(chip, iface, alts, fmt, rate);
253 }
254
255 return -EINVAL;
256}
257
258/*
259 * find a matching format and set up the interface
260 */
261static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
262{
263 struct usb_device *dev = subs->dev;
264 struct usb_host_interface *alts;
265 struct usb_interface_descriptor *altsd;
266 struct usb_interface *iface;
267 unsigned int ep, attr;
268 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
269 int err;
270
271 iface = usb_ifnum_to_if(dev, fmt->iface);
272 if (WARN_ON(!iface))
273 return -EINVAL;
274 alts = &iface->altsetting[fmt->altset_idx];
275 altsd = get_iface_desc(alts);
276 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
277 return -EINVAL;
278
279 if (fmt == subs->cur_audiofmt)
280 return 0;
281
282 /* close the old interface */
283 if (subs->interface >= 0 && subs->interface != fmt->iface) {
284 if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
285 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
286 dev->devnum, fmt->iface, fmt->altsetting);
287 return -EIO;
288 }
289 subs->interface = -1;
290 subs->altset_idx = 0;
291 }
292
293 /* set interface */
294 if (subs->interface != fmt->iface || subs->altset_idx != fmt->altset_idx) {
295 if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
296 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
297 dev->devnum, fmt->iface, fmt->altsetting);
298 return -EIO;
299 }
300 snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
301 subs->interface = fmt->iface;
302 subs->altset_idx = fmt->altset_idx;
303 }
304
305 /* create a data pipe */
306 ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
307 if (is_playback)
308 subs->datapipe = usb_sndisocpipe(dev, ep);
309 else
310 subs->datapipe = usb_rcvisocpipe(dev, ep);
311 subs->datainterval = fmt->datainterval;
312 subs->syncpipe = subs->syncinterval = 0;
313 subs->maxpacksize = fmt->maxpacksize;
314 subs->fill_max = 0;
315
316 /* we need a sync pipe in async OUT or adaptive IN mode */
317 /* check the number of EP, since some devices have broken
318 * descriptors which fool us. if it has only one EP,
319 * assume it as adaptive-out or sync-in.
320 */
321 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
322 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
323 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
324 altsd->bNumEndpoints >= 2) {
325 /* check sync-pipe endpoint */
326 /* ... and check descriptor size before accessing bSynchAddress
327 because there is a version of the SB Audigy 2 NX firmware lacking
328 the audio fields in the endpoint descriptors */
329 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
330 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
331 get_endpoint(alts, 1)->bSynchAddress != 0)) {
332 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
333 dev->devnum, fmt->iface, fmt->altsetting);
334 return -EINVAL;
335 }
336 ep = get_endpoint(alts, 1)->bEndpointAddress;
337 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
338 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
339 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
340 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
341 dev->devnum, fmt->iface, fmt->altsetting);
342 return -EINVAL;
343 }
344 ep &= USB_ENDPOINT_NUMBER_MASK;
345 if (is_playback)
346 subs->syncpipe = usb_rcvisocpipe(dev, ep);
347 else
348 subs->syncpipe = usb_sndisocpipe(dev, ep);
349 if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
350 get_endpoint(alts, 1)->bRefresh >= 1 &&
351 get_endpoint(alts, 1)->bRefresh <= 9)
352 subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
353 else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
354 subs->syncinterval = 1;
355 else if (get_endpoint(alts, 1)->bInterval >= 1 &&
356 get_endpoint(alts, 1)->bInterval <= 16)
357 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
358 else
359 subs->syncinterval = 3;
360 }
361
362 /* always fill max packet size */
363 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
364 subs->fill_max = 1;
365
366 if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0)
367 return err;
368
369 subs->cur_audiofmt = fmt;
370
371 snd_usb_set_format_quirk(subs, fmt);
372
373#if 0
374 printk(KERN_DEBUG
375 "setting done: format = %d, rate = %d..%d, channels = %d\n",
376 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
377 printk(KERN_DEBUG
378 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
379 subs->datapipe, subs->syncpipe);
380#endif
381
382 return 0;
383}
384
385/*
386 * hw_params callback
387 *
388 * allocate a buffer and set the given audio format.
389 *
390 * so far we use a physically linear buffer although packetize transfer
391 * doesn't need a continuous area.
392 * if sg buffer is supported on the later version of alsa, we'll follow
393 * that.
394 */
395static int snd_usb_hw_params(struct snd_pcm_substream *substream,
396 struct snd_pcm_hw_params *hw_params)
397{
398 struct snd_usb_substream *subs = substream->runtime->private_data;
399 struct audioformat *fmt;
400 unsigned int channels, rate, format;
401 int ret, changed;
402
403 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
404 params_buffer_bytes(hw_params));
405 if (ret < 0)
406 return ret;
407
408 format = params_format(hw_params);
409 rate = params_rate(hw_params);
410 channels = params_channels(hw_params);
411 fmt = find_format(subs, format, rate, channels);
412 if (!fmt) {
413 snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
414 format, rate, channels);
415 return -EINVAL;
416 }
417
418 changed = subs->cur_audiofmt != fmt ||
419 subs->period_bytes != params_period_bytes(hw_params) ||
420 subs->cur_rate != rate;
421 if ((ret = set_format(subs, fmt)) < 0)
422 return ret;
423
424 if (subs->cur_rate != rate) {
425 struct usb_host_interface *alts;
426 struct usb_interface *iface;
427 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
428 alts = &iface->altsetting[fmt->altset_idx];
429 ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate);
430 if (ret < 0)
431 return ret;
432 subs->cur_rate = rate;
433 }
434
435 if (changed) {
436 /* format changed */
437 snd_usb_release_substream_urbs(subs, 0);
438 /* influenced: period_bytes, channels, rate, format, */
439 ret = snd_usb_init_substream_urbs(subs, params_period_bytes(hw_params),
440 params_rate(hw_params),
441 snd_pcm_format_physical_width(params_format(hw_params)) *
442 params_channels(hw_params));
443 }
444
445 return ret;
446}
447
448/*
449 * hw_free callback
450 *
451 * reset the audio format and release the buffer
452 */
453static int snd_usb_hw_free(struct snd_pcm_substream *substream)
454{
455 struct snd_usb_substream *subs = substream->runtime->private_data;
456
457 subs->cur_audiofmt = NULL;
458 subs->cur_rate = 0;
459 subs->period_bytes = 0;
460 if (!subs->stream->chip->shutdown)
461 snd_usb_release_substream_urbs(subs, 0);
462 return snd_pcm_lib_free_vmalloc_buffer(substream);
463}
464
465/*
466 * prepare callback
467 *
468 * only a few subtle things...
469 */
470static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
471{
472 struct snd_pcm_runtime *runtime = substream->runtime;
473 struct snd_usb_substream *subs = runtime->private_data;
474
475 if (! subs->cur_audiofmt) {
476 snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
477 return -ENXIO;
478 }
479
480 /* some unit conversions in runtime */
481 subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
482 subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
483
484 /* reset the pointer */
485 subs->hwptr_done = 0;
486 subs->transfer_done = 0;
487 subs->phase = 0;
488 runtime->delay = 0;
489
490 return snd_usb_substream_prepare(subs, runtime);
491}
492
493static struct snd_pcm_hardware snd_usb_hardware =
494{
495 .info = SNDRV_PCM_INFO_MMAP |
496 SNDRV_PCM_INFO_MMAP_VALID |
497 SNDRV_PCM_INFO_BATCH |
498 SNDRV_PCM_INFO_INTERLEAVED |
499 SNDRV_PCM_INFO_BLOCK_TRANSFER |
500 SNDRV_PCM_INFO_PAUSE,
501 .buffer_bytes_max = 1024 * 1024,
502 .period_bytes_min = 64,
503 .period_bytes_max = 512 * 1024,
504 .periods_min = 2,
505 .periods_max = 1024,
506};
507
508static int hw_check_valid_format(struct snd_usb_substream *subs,
509 struct snd_pcm_hw_params *params,
510 struct audioformat *fp)
511{
512 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
513 struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
514 struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
515 struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
516 struct snd_mask check_fmts;
517 unsigned int ptime;
518
519 /* check the format */
520 snd_mask_none(&check_fmts);
521 check_fmts.bits[0] = (u32)fp->formats;
522 check_fmts.bits[1] = (u32)(fp->formats >> 32);
523 snd_mask_intersect(&check_fmts, fmts);
524 if (snd_mask_empty(&check_fmts)) {
525 hwc_debug(" > check: no supported format %d\n", fp->format);
526 return 0;
527 }
528 /* check the channels */
529 if (fp->channels < ct->min || fp->channels > ct->max) {
530 hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
531 return 0;
532 }
533 /* check the rate is within the range */
534 if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
535 hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
536 return 0;
537 }
538 if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
539 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
540 return 0;
541 }
542 /* check whether the period time is >= the data packet interval */
543 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
544 ptime = 125 * (1 << fp->datainterval);
545 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
546 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
547 return 0;
548 }
549 }
550 return 1;
551}
552
553static int hw_rule_rate(struct snd_pcm_hw_params *params,
554 struct snd_pcm_hw_rule *rule)
555{
556 struct snd_usb_substream *subs = rule->private;
557 struct list_head *p;
558 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
559 unsigned int rmin, rmax;
560 int changed;
561
562 hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
563 changed = 0;
564 rmin = rmax = 0;
565 list_for_each(p, &subs->fmt_list) {
566 struct audioformat *fp;
567 fp = list_entry(p, struct audioformat, list);
568 if (!hw_check_valid_format(subs, params, fp))
569 continue;
570 if (changed++) {
571 if (rmin > fp->rate_min)
572 rmin = fp->rate_min;
573 if (rmax < fp->rate_max)
574 rmax = fp->rate_max;
575 } else {
576 rmin = fp->rate_min;
577 rmax = fp->rate_max;
578 }
579 }
580
581 if (!changed) {
582 hwc_debug(" --> get empty\n");
583 it->empty = 1;
584 return -EINVAL;
585 }
586
587 changed = 0;
588 if (it->min < rmin) {
589 it->min = rmin;
590 it->openmin = 0;
591 changed = 1;
592 }
593 if (it->max > rmax) {
594 it->max = rmax;
595 it->openmax = 0;
596 changed = 1;
597 }
598 if (snd_interval_checkempty(it)) {
599 it->empty = 1;
600 return -EINVAL;
601 }
602 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
603 return changed;
604}
605
606
607static int hw_rule_channels(struct snd_pcm_hw_params *params,
608 struct snd_pcm_hw_rule *rule)
609{
610 struct snd_usb_substream *subs = rule->private;
611 struct list_head *p;
612 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
613 unsigned int rmin, rmax;
614 int changed;
615
616 hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
617 changed = 0;
618 rmin = rmax = 0;
619 list_for_each(p, &subs->fmt_list) {
620 struct audioformat *fp;
621 fp = list_entry(p, struct audioformat, list);
622 if (!hw_check_valid_format(subs, params, fp))
623 continue;
624 if (changed++) {
625 if (rmin > fp->channels)
626 rmin = fp->channels;
627 if (rmax < fp->channels)
628 rmax = fp->channels;
629 } else {
630 rmin = fp->channels;
631 rmax = fp->channels;
632 }
633 }
634
635 if (!changed) {
636 hwc_debug(" --> get empty\n");
637 it->empty = 1;
638 return -EINVAL;
639 }
640
641 changed = 0;
642 if (it->min < rmin) {
643 it->min = rmin;
644 it->openmin = 0;
645 changed = 1;
646 }
647 if (it->max > rmax) {
648 it->max = rmax;
649 it->openmax = 0;
650 changed = 1;
651 }
652 if (snd_interval_checkempty(it)) {
653 it->empty = 1;
654 return -EINVAL;
655 }
656 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
657 return changed;
658}
659
660static int hw_rule_format(struct snd_pcm_hw_params *params,
661 struct snd_pcm_hw_rule *rule)
662{
663 struct snd_usb_substream *subs = rule->private;
664 struct list_head *p;
665 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
666 u64 fbits;
667 u32 oldbits[2];
668 int changed;
669
670 hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
671 fbits = 0;
672 list_for_each(p, &subs->fmt_list) {
673 struct audioformat *fp;
674 fp = list_entry(p, struct audioformat, list);
675 if (!hw_check_valid_format(subs, params, fp))
676 continue;
677 fbits |= fp->formats;
678 }
679
680 oldbits[0] = fmt->bits[0];
681 oldbits[1] = fmt->bits[1];
682 fmt->bits[0] &= (u32)fbits;
683 fmt->bits[1] &= (u32)(fbits >> 32);
684 if (!fmt->bits[0] && !fmt->bits[1]) {
685 hwc_debug(" --> get empty\n");
686 return -EINVAL;
687 }
688 changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
689 hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
690 return changed;
691}
692
693static int hw_rule_period_time(struct snd_pcm_hw_params *params,
694 struct snd_pcm_hw_rule *rule)
695{
696 struct snd_usb_substream *subs = rule->private;
697 struct audioformat *fp;
698 struct snd_interval *it;
699 unsigned char min_datainterval;
700 unsigned int pmin;
701 int changed;
702
703 it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
704 hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
705 min_datainterval = 0xff;
706 list_for_each_entry(fp, &subs->fmt_list, list) {
707 if (!hw_check_valid_format(subs, params, fp))
708 continue;
709 min_datainterval = min(min_datainterval, fp->datainterval);
710 }
711 if (min_datainterval == 0xff) {
712 hwc_debug(" --> get emtpy\n");
713 it->empty = 1;
714 return -EINVAL;
715 }
716 pmin = 125 * (1 << min_datainterval);
717 changed = 0;
718 if (it->min < pmin) {
719 it->min = pmin;
720 it->openmin = 0;
721 changed = 1;
722 }
723 if (snd_interval_checkempty(it)) {
724 it->empty = 1;
725 return -EINVAL;
726 }
727 hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
728 return changed;
729}
730
731/*
732 * If the device supports unusual bit rates, does the request meet these?
733 */
734static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
735 struct snd_usb_substream *subs)
736{
737 struct audioformat *fp;
738 int count = 0, needs_knot = 0;
739 int err;
740
741 list_for_each_entry(fp, &subs->fmt_list, list) {
742 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
743 return 0;
744 count += fp->nr_rates;
745 if (fp->rates & SNDRV_PCM_RATE_KNOT)
746 needs_knot = 1;
747 }
748 if (!needs_knot)
749 return 0;
750
751 subs->rate_list.count = count;
752 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
753 subs->rate_list.mask = 0;
754 count = 0;
755 list_for_each_entry(fp, &subs->fmt_list, list) {
756 int i;
757 for (i = 0; i < fp->nr_rates; i++)
758 subs->rate_list.list[count++] = fp->rate_table[i];
759 }
760 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
761 &subs->rate_list);
762 if (err < 0)
763 return err;
764
765 return 0;
766}
767
768
769/*
770 * set up the runtime hardware information.
771 */
772
773static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
774{
775 struct list_head *p;
776 unsigned int pt, ptmin;
777 int param_period_time_if_needed;
778 int err;
779
780 runtime->hw.formats = subs->formats;
781
782 runtime->hw.rate_min = 0x7fffffff;
783 runtime->hw.rate_max = 0;
784 runtime->hw.channels_min = 256;
785 runtime->hw.channels_max = 0;
786 runtime->hw.rates = 0;
787 ptmin = UINT_MAX;
788 /* check min/max rates and channels */
789 list_for_each(p, &subs->fmt_list) {
790 struct audioformat *fp;
791 fp = list_entry(p, struct audioformat, list);
792 runtime->hw.rates |= fp->rates;
793 if (runtime->hw.rate_min > fp->rate_min)
794 runtime->hw.rate_min = fp->rate_min;
795 if (runtime->hw.rate_max < fp->rate_max)
796 runtime->hw.rate_max = fp->rate_max;
797 if (runtime->hw.channels_min > fp->channels)
798 runtime->hw.channels_min = fp->channels;
799 if (runtime->hw.channels_max < fp->channels)
800 runtime->hw.channels_max = fp->channels;
801 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
802 /* FIXME: there might be more than one audio formats... */
803 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
804 fp->frame_size;
805 }
806 pt = 125 * (1 << fp->datainterval);
807 ptmin = min(ptmin, pt);
808 }
809
810 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
811 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
812 /* full speed devices have fixed data packet interval */
813 ptmin = 1000;
814 if (ptmin == 1000)
815 /* if period time doesn't go below 1 ms, no rules needed */
816 param_period_time_if_needed = -1;
817 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
818 ptmin, UINT_MAX);
819
820 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
821 hw_rule_rate, subs,
822 SNDRV_PCM_HW_PARAM_FORMAT,
823 SNDRV_PCM_HW_PARAM_CHANNELS,
824 param_period_time_if_needed,
825 -1)) < 0)
826 return err;
827 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
828 hw_rule_channels, subs,
829 SNDRV_PCM_HW_PARAM_FORMAT,
830 SNDRV_PCM_HW_PARAM_RATE,
831 param_period_time_if_needed,
832 -1)) < 0)
833 return err;
834 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
835 hw_rule_format, subs,
836 SNDRV_PCM_HW_PARAM_RATE,
837 SNDRV_PCM_HW_PARAM_CHANNELS,
838 param_period_time_if_needed,
839 -1)) < 0)
840 return err;
841 if (param_period_time_if_needed >= 0) {
842 err = snd_pcm_hw_rule_add(runtime, 0,
843 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
844 hw_rule_period_time, subs,
845 SNDRV_PCM_HW_PARAM_FORMAT,
846 SNDRV_PCM_HW_PARAM_CHANNELS,
847 SNDRV_PCM_HW_PARAM_RATE,
848 -1);
849 if (err < 0)
850 return err;
851 }
852 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
853 return err;
854 return 0;
855}
856
857static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
858{
859 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
860 struct snd_pcm_runtime *runtime = substream->runtime;
861 struct snd_usb_substream *subs = &as->substream[direction];
862
863 subs->interface = -1;
864 subs->altset_idx = 0;
865 runtime->hw = snd_usb_hardware;
866 runtime->private_data = subs;
867 subs->pcm_substream = substream;
868 return setup_hw_info(runtime, subs);
869}
870
871static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
872{
873 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
874 struct snd_usb_substream *subs = &as->substream[direction];
875
876 if (!as->chip->shutdown && subs->interface >= 0) {
877 usb_set_interface(subs->dev, subs->interface, 0);
878 subs->interface = -1;
879 }
880 subs->pcm_substream = NULL;
881 return 0;
882}
883
884static int snd_usb_playback_open(struct snd_pcm_substream *substream)
885{
886 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
887}
888
889static int snd_usb_playback_close(struct snd_pcm_substream *substream)
890{
891 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
892}
893
894static int snd_usb_capture_open(struct snd_pcm_substream *substream)
895{
896 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
897}
898
899static int snd_usb_capture_close(struct snd_pcm_substream *substream)
900{
901 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
902}
903
904static struct snd_pcm_ops snd_usb_playback_ops = {
905 .open = snd_usb_playback_open,
906 .close = snd_usb_playback_close,
907 .ioctl = snd_pcm_lib_ioctl,
908 .hw_params = snd_usb_hw_params,
909 .hw_free = snd_usb_hw_free,
910 .prepare = snd_usb_pcm_prepare,
911 .trigger = snd_usb_substream_playback_trigger,
912 .pointer = snd_usb_pcm_pointer,
913 .page = snd_pcm_lib_get_vmalloc_page,
914 .mmap = snd_pcm_lib_mmap_vmalloc,
915};
916
917static struct snd_pcm_ops snd_usb_capture_ops = {
918 .open = snd_usb_capture_open,
919 .close = snd_usb_capture_close,
920 .ioctl = snd_pcm_lib_ioctl,
921 .hw_params = snd_usb_hw_params,
922 .hw_free = snd_usb_hw_free,
923 .prepare = snd_usb_pcm_prepare,
924 .trigger = snd_usb_substream_capture_trigger,
925 .pointer = snd_usb_pcm_pointer,
926 .page = snd_pcm_lib_get_vmalloc_page,
927 .mmap = snd_pcm_lib_mmap_vmalloc,
928};
929
930void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream)
931{
932 snd_pcm_set_ops(pcm, stream,
933 stream == SNDRV_PCM_STREAM_PLAYBACK ?
934 &snd_usb_playback_ops : &snd_usb_capture_ops);
935}
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h
new file mode 100644
index 000000000000..1c931b68f3b5
--- /dev/null
+++ b/sound/usb/pcm.h
@@ -0,0 +1,14 @@
1#ifndef __USBAUDIO_PCM_H
2#define __USBAUDIO_PCM_H
3
4void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream);
5
6int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
7 struct usb_host_interface *alts,
8 struct audioformat *fmt);
9
10int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
11 struct usb_host_interface *alts,
12 struct audioformat *fmt, int rate);
13
14#endif /* __USBAUDIO_PCM_H */
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
new file mode 100644
index 000000000000..f5e3f356b95f
--- /dev/null
+++ b/sound/usb/proc.c
@@ -0,0 +1,168 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/init.h>
19#include <linux/usb.h>
20
21#include <sound/core.h>
22#include <sound/info.h>
23#include <sound/pcm.h>
24
25#include "usbaudio.h"
26#include "helper.h"
27#include "card.h"
28#include "proc.h"
29
30/* convert our full speed USB rate into sampling rate in Hz */
31static inline unsigned get_full_speed_hz(unsigned int usb_rate)
32{
33 return (usb_rate * 125 + (1 << 12)) >> 13;
34}
35
36/* convert our high speed USB rate into sampling rate in Hz */
37static inline unsigned get_high_speed_hz(unsigned int usb_rate)
38{
39 return (usb_rate * 125 + (1 << 9)) >> 10;
40}
41
42/*
43 * common proc files to show the usb device info
44 */
45static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
46{
47 struct snd_usb_audio *chip = entry->private_data;
48 if (!chip->shutdown)
49 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
50}
51
52static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
53{
54 struct snd_usb_audio *chip = entry->private_data;
55 if (!chip->shutdown)
56 snd_iprintf(buffer, "%04x:%04x\n",
57 USB_ID_VENDOR(chip->usb_id),
58 USB_ID_PRODUCT(chip->usb_id));
59}
60
61void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
62{
63 struct snd_info_entry *entry;
64 if (!snd_card_proc_new(chip->card, "usbbus", &entry))
65 snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
66 if (!snd_card_proc_new(chip->card, "usbid", &entry))
67 snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
68}
69
70/*
71 * proc interface for list the supported pcm formats
72 */
73static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
74{
75 struct list_head *p;
76 static char *sync_types[4] = {
77 "NONE", "ASYNC", "ADAPTIVE", "SYNC"
78 };
79
80 list_for_each(p, &subs->fmt_list) {
81 struct audioformat *fp;
82 snd_pcm_format_t fmt;
83 fp = list_entry(p, struct audioformat, list);
84 snd_iprintf(buffer, " Interface %d\n", fp->iface);
85 snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
86 snd_iprintf(buffer, " Format:");
87 for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt)
88 if (fp->formats & (1uLL << fmt))
89 snd_iprintf(buffer, " %s",
90 snd_pcm_format_name(fmt));
91 snd_iprintf(buffer, "\n");
92 snd_iprintf(buffer, " Channels: %d\n", fp->channels);
93 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
94 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
95 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
96 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
97 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
98 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
99 fp->rate_min, fp->rate_max);
100 } else {
101 unsigned int i;
102 snd_iprintf(buffer, " Rates: ");
103 for (i = 0; i < fp->nr_rates; i++) {
104 if (i > 0)
105 snd_iprintf(buffer, ", ");
106 snd_iprintf(buffer, "%d", fp->rate_table[i]);
107 }
108 snd_iprintf(buffer, "\n");
109 }
110 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
111 snd_iprintf(buffer, " Data packet interval: %d us\n",
112 125 * (1 << fp->datainterval));
113 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
114 // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
115 }
116}
117
118static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
119{
120 if (subs->running) {
121 unsigned int i;
122 snd_iprintf(buffer, " Status: Running\n");
123 snd_iprintf(buffer, " Interface = %d\n", subs->interface);
124 snd_iprintf(buffer, " Altset = %d\n", subs->altset_idx);
125 snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs);
126 for (i = 0; i < subs->nurbs; i++)
127 snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
128 snd_iprintf(buffer, "]\n");
129 snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize);
130 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
131 snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
132 ? get_full_speed_hz(subs->freqm)
133 : get_high_speed_hz(subs->freqm),
134 subs->freqm >> 16, subs->freqm & 0xffff);
135 } else {
136 snd_iprintf(buffer, " Status: Stop\n");
137 }
138}
139
140static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
141{
142 struct snd_usb_stream *stream = entry->private_data;
143
144 snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
145
146 if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
147 snd_iprintf(buffer, "\nPlayback:\n");
148 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
149 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
150 }
151 if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
152 snd_iprintf(buffer, "\nCapture:\n");
153 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
154 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
155 }
156}
157
158void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream)
159{
160 struct snd_info_entry *entry;
161 char name[32];
162 struct snd_card *card = stream->chip->card;
163
164 sprintf(name, "stream%d", stream->pcm_index);
165 if (!snd_card_proc_new(card, name, &entry))
166 snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
167}
168
diff --git a/sound/usb/proc.h b/sound/usb/proc.h
new file mode 100644
index 000000000000..a45b765e4cf1
--- /dev/null
+++ b/sound/usb/proc.h
@@ -0,0 +1,8 @@
1#ifndef __USBAUDIO_PROC_H
2#define __USBAUDIO_PROC_H
3
4void snd_usb_audio_create_proc(struct snd_usb_audio *chip);
5void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream);
6
7#endif /* __USBAUDIO_PROC_H */
8
diff --git a/sound/usb/usbquirks.h b/sound/usb/quirks-table.h
index 2b426c1fd0e8..91ddef31bcbd 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/quirks-table.h
@@ -279,7 +279,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
279 .ifnum = 0, 279 .ifnum = 0,
280 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 280 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
281 .data = & (const struct audioformat) { 281 .data = & (const struct audioformat) {
282 .format = SNDRV_PCM_FORMAT_S16_LE, 282 .formats = SNDRV_PCM_FMTBIT_S16_LE,
283 .channels = 4, 283 .channels = 4,
284 .iface = 0, 284 .iface = 0,
285 .altsetting = 1, 285 .altsetting = 1,
@@ -296,7 +296,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
296 .ifnum = 1, 296 .ifnum = 1,
297 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 297 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
298 .data = & (const struct audioformat) { 298 .data = & (const struct audioformat) {
299 .format = SNDRV_PCM_FORMAT_S16_LE, 299 .formats = SNDRV_PCM_FMTBIT_S16_LE,
300 .channels = 2, 300 .channels = 2,
301 .iface = 1, 301 .iface = 1,
302 .altsetting = 1, 302 .altsetting = 1,
@@ -580,7 +580,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
580 .ifnum = 0, 580 .ifnum = 0,
581 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 581 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
582 .data = & (const struct audioformat) { 582 .data = & (const struct audioformat) {
583 .format = SNDRV_PCM_FORMAT_S24_3LE, 583 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
584 .channels = 2, 584 .channels = 2,
585 .iface = 0, 585 .iface = 0,
586 .altsetting = 1, 586 .altsetting = 1,
@@ -597,7 +597,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
597 .ifnum = 1, 597 .ifnum = 1,
598 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 598 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
599 .data = & (const struct audioformat) { 599 .data = & (const struct audioformat) {
600 .format = SNDRV_PCM_FORMAT_S24_3LE, 600 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
601 .channels = 2, 601 .channels = 2,
602 .iface = 1, 602 .iface = 1,
603 .altsetting = 1, 603 .altsetting = 1,
@@ -793,7 +793,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
793 .ifnum = 1, 793 .ifnum = 1,
794 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 794 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
795 .data = & (const struct audioformat) { 795 .data = & (const struct audioformat) {
796 .format = SNDRV_PCM_FORMAT_S24_3LE, 796 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
797 .channels = 2, 797 .channels = 2,
798 .iface = 1, 798 .iface = 1,
799 .altsetting = 1, 799 .altsetting = 1,
@@ -810,7 +810,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
810 .ifnum = 2, 810 .ifnum = 2,
811 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 811 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
812 .data = & (const struct audioformat) { 812 .data = & (const struct audioformat) {
813 .format = SNDRV_PCM_FORMAT_S24_3LE, 813 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
814 .channels = 2, 814 .channels = 2,
815 .iface = 2, 815 .iface = 2,
816 .altsetting = 1, 816 .altsetting = 1,
@@ -1826,6 +1826,60 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1826 } 1826 }
1827 } 1827 }
1828}, 1828},
1829{
1830 USB_DEVICE(0x0763, 0x2080),
1831 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1832 /* .vendor_name = "M-Audio", */
1833 /* .product_name = "Fast Track Ultra 8", */
1834 .ifnum = QUIRK_ANY_INTERFACE,
1835 .type = QUIRK_COMPOSITE,
1836 .data = & (const struct snd_usb_audio_quirk[]) {
1837 {
1838 .ifnum = 0,
1839 .type = QUIRK_IGNORE_INTERFACE
1840 },
1841 {
1842 .ifnum = 1,
1843 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1844 },
1845 {
1846 .ifnum = 2,
1847 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1848 },
1849 /* interface 3 (MIDI) is standard compliant */
1850 {
1851 .ifnum = -1
1852 }
1853 }
1854 }
1855},
1856{
1857 USB_DEVICE(0x0763, 0x2081),
1858 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1859 /* .vendor_name = "M-Audio", */
1860 /* .product_name = "Fast Track Ultra 8R", */
1861 .ifnum = QUIRK_ANY_INTERFACE,
1862 .type = QUIRK_COMPOSITE,
1863 .data = & (const struct snd_usb_audio_quirk[]) {
1864 {
1865 .ifnum = 0,
1866 .type = QUIRK_IGNORE_INTERFACE
1867 },
1868 {
1869 .ifnum = 1,
1870 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1871 },
1872 {
1873 .ifnum = 2,
1874 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1875 },
1876 /* interface 3 (MIDI) is standard compliant */
1877 {
1878 .ifnum = -1
1879 }
1880 }
1881 }
1882},
1829 1883
1830/* Casio devices */ 1884/* Casio devices */
1831{ 1885{
@@ -2203,7 +2257,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2203 .ifnum = 1, 2257 .ifnum = 1,
2204 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 2258 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
2205 .data = &(const struct audioformat) { 2259 .data = &(const struct audioformat) {
2206 .format = SNDRV_PCM_FORMAT_S24_3BE, 2260 .formats = SNDRV_PCM_FMTBIT_S24_3BE,
2207 .channels = 2, 2261 .channels = 2,
2208 .iface = 1, 2262 .iface = 1,
2209 .altsetting = 1, 2263 .altsetting = 1,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
new file mode 100644
index 000000000000..136e5b4cf6de
--- /dev/null
+++ b/sound/usb/quirks.c
@@ -0,0 +1,594 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <linux/usb.h>
20#include <linux/usb/audio.h>
21
22#include <sound/core.h>
23#include <sound/info.h>
24#include <sound/pcm.h>
25
26#include "usbaudio.h"
27#include "card.h"
28#include "mixer.h"
29#include "mixer_quirks.h"
30#include "midi.h"
31#include "quirks.h"
32#include "helper.h"
33#include "endpoint.h"
34#include "pcm.h"
35
36/*
37 * handle the quirks for the contained interfaces
38 */
39static int create_composite_quirk(struct snd_usb_audio *chip,
40 struct usb_interface *iface,
41 struct usb_driver *driver,
42 const struct snd_usb_audio_quirk *quirk)
43{
44 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
45 int err;
46
47 for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
48 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
49 if (!iface)
50 continue;
51 if (quirk->ifnum != probed_ifnum &&
52 usb_interface_claimed(iface))
53 continue;
54 err = snd_usb_create_quirk(chip, iface, driver, quirk);
55 if (err < 0)
56 return err;
57 if (quirk->ifnum != probed_ifnum)
58 usb_driver_claim_interface(driver, iface, (void *)-1L);
59 }
60 return 0;
61}
62
63static int ignore_interface_quirk(struct snd_usb_audio *chip,
64 struct usb_interface *iface,
65 struct usb_driver *driver,
66 const struct snd_usb_audio_quirk *quirk)
67{
68 return 0;
69}
70
71
72/*
73 * Allow alignment on audio sub-slot (channel samples) rather than
74 * on audio slots (audio frames)
75 */
76static int create_align_transfer_quirk(struct snd_usb_audio *chip,
77 struct usb_interface *iface,
78 struct usb_driver *driver,
79 const struct snd_usb_audio_quirk *quirk)
80{
81 chip->txfr_quirk = 1;
82 return 1; /* Continue with creating streams and mixer */
83}
84
85static int create_any_midi_quirk(struct snd_usb_audio *chip,
86 struct usb_interface *intf,
87 struct usb_driver *driver,
88 const struct snd_usb_audio_quirk *quirk)
89{
90 return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
91}
92
93/*
94 * create a stream for an interface with proper descriptors
95 */
96static int create_standard_audio_quirk(struct snd_usb_audio *chip,
97 struct usb_interface *iface,
98 struct usb_driver *driver,
99 const struct snd_usb_audio_quirk *quirk)
100{
101 struct usb_host_interface *alts;
102 struct usb_interface_descriptor *altsd;
103 int err;
104
105 alts = &iface->altsetting[0];
106 altsd = get_iface_desc(alts);
107 err = snd_usb_parse_audio_endpoints(chip, altsd->bInterfaceNumber);
108 if (err < 0) {
109 snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
110 altsd->bInterfaceNumber, err);
111 return err;
112 }
113 /* reset the current interface */
114 usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
115 return 0;
116}
117
118/*
119 * create a stream for an endpoint/altsetting without proper descriptors
120 */
121static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
122 struct usb_interface *iface,
123 struct usb_driver *driver,
124 const struct snd_usb_audio_quirk *quirk)
125{
126 struct audioformat *fp;
127 struct usb_host_interface *alts;
128 int stream, err;
129 unsigned *rate_table = NULL;
130
131 fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
132 if (! fp) {
133 snd_printk(KERN_ERR "cannot memdup\n");
134 return -ENOMEM;
135 }
136 if (fp->nr_rates > 0) {
137 rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
138 if (!rate_table) {
139 kfree(fp);
140 return -ENOMEM;
141 }
142 memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
143 fp->rate_table = rate_table;
144 }
145
146 stream = (fp->endpoint & USB_DIR_IN)
147 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
148 err = snd_usb_add_audio_endpoint(chip, stream, fp);
149 if (err < 0) {
150 kfree(fp);
151 kfree(rate_table);
152 return err;
153 }
154 if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
155 fp->altset_idx >= iface->num_altsetting) {
156 kfree(fp);
157 kfree(rate_table);
158 return -EINVAL;
159 }
160 alts = &iface->altsetting[fp->altset_idx];
161 fp->datainterval = snd_usb_parse_datainterval(chip, alts);
162 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
163 usb_set_interface(chip->dev, fp->iface, 0);
164 snd_usb_init_pitch(chip, fp->iface, alts, fp);
165 snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
166 return 0;
167}
168
169/*
170 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
171 * The only way to detect the sample rate is by looking at wMaxPacketSize.
172 */
173static int create_uaxx_quirk(struct snd_usb_audio *chip,
174 struct usb_interface *iface,
175 struct usb_driver *driver,
176 const struct snd_usb_audio_quirk *quirk)
177{
178 static const struct audioformat ua_format = {
179 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
180 .channels = 2,
181 .fmt_type = UAC_FORMAT_TYPE_I,
182 .altsetting = 1,
183 .altset_idx = 1,
184 .rates = SNDRV_PCM_RATE_CONTINUOUS,
185 };
186 struct usb_host_interface *alts;
187 struct usb_interface_descriptor *altsd;
188 struct audioformat *fp;
189 int stream, err;
190
191 /* both PCM and MIDI interfaces have 2 or more altsettings */
192 if (iface->num_altsetting < 2)
193 return -ENXIO;
194 alts = &iface->altsetting[1];
195 altsd = get_iface_desc(alts);
196
197 if (altsd->bNumEndpoints == 2) {
198 static const struct snd_usb_midi_endpoint_info ua700_ep = {
199 .out_cables = 0x0003,
200 .in_cables = 0x0003
201 };
202 static const struct snd_usb_audio_quirk ua700_quirk = {
203 .type = QUIRK_MIDI_FIXED_ENDPOINT,
204 .data = &ua700_ep
205 };
206 static const struct snd_usb_midi_endpoint_info uaxx_ep = {
207 .out_cables = 0x0001,
208 .in_cables = 0x0001
209 };
210 static const struct snd_usb_audio_quirk uaxx_quirk = {
211 .type = QUIRK_MIDI_FIXED_ENDPOINT,
212 .data = &uaxx_ep
213 };
214 const struct snd_usb_audio_quirk *quirk =
215 chip->usb_id == USB_ID(0x0582, 0x002b)
216 ? &ua700_quirk : &uaxx_quirk;
217 return snd_usbmidi_create(chip->card, iface,
218 &chip->midi_list, quirk);
219 }
220
221 if (altsd->bNumEndpoints != 1)
222 return -ENXIO;
223
224 fp = kmalloc(sizeof(*fp), GFP_KERNEL);
225 if (!fp)
226 return -ENOMEM;
227 memcpy(fp, &ua_format, sizeof(*fp));
228
229 fp->iface = altsd->bInterfaceNumber;
230 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
231 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
232 fp->datainterval = 0;
233 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
234
235 switch (fp->maxpacksize) {
236 case 0x120:
237 fp->rate_max = fp->rate_min = 44100;
238 break;
239 case 0x138:
240 case 0x140:
241 fp->rate_max = fp->rate_min = 48000;
242 break;
243 case 0x258:
244 case 0x260:
245 fp->rate_max = fp->rate_min = 96000;
246 break;
247 default:
248 snd_printk(KERN_ERR "unknown sample rate\n");
249 kfree(fp);
250 return -ENXIO;
251 }
252
253 stream = (fp->endpoint & USB_DIR_IN)
254 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
255 err = snd_usb_add_audio_endpoint(chip, stream, fp);
256 if (err < 0) {
257 kfree(fp);
258 return err;
259 }
260 usb_set_interface(chip->dev, fp->iface, 0);
261 return 0;
262}
263
264/*
265 * audio-interface quirks
266 *
267 * returns zero if no standard audio/MIDI parsing is needed.
268 * returns a postive value if standard audio/midi interfaces are parsed
269 * after this.
270 * returns a negative value at error.
271 */
272int snd_usb_create_quirk(struct snd_usb_audio *chip,
273 struct usb_interface *iface,
274 struct usb_driver *driver,
275 const struct snd_usb_audio_quirk *quirk)
276{
277 typedef int (*quirk_func_t)(struct snd_usb_audio *,
278 struct usb_interface *,
279 struct usb_driver *,
280 const struct snd_usb_audio_quirk *);
281 static const quirk_func_t quirk_funcs[] = {
282 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
283 [QUIRK_COMPOSITE] = create_composite_quirk,
284 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
285 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
286 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
287 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
288 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
289 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk,
290 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
291 [QUIRK_MIDI_CME] = create_any_midi_quirk,
292 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
293 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
294 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
295 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
296 };
297
298 if (quirk->type < QUIRK_TYPE_COUNT) {
299 return quirk_funcs[quirk->type](chip, iface, driver, quirk);
300 } else {
301 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
302 return -ENXIO;
303 }
304}
305
306/*
307 * boot quirks
308 */
309
310#define EXTIGY_FIRMWARE_SIZE_OLD 794
311#define EXTIGY_FIRMWARE_SIZE_NEW 483
312
313static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
314{
315 struct usb_host_config *config = dev->actconfig;
316 int err;
317
318 if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
319 le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
320 snd_printdd("sending Extigy boot sequence...\n");
321 /* Send message to force it to reconnect with full interface. */
322 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
323 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000);
324 if (err < 0) snd_printdd("error sending boot message: %d\n", err);
325 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
326 &dev->descriptor, sizeof(dev->descriptor));
327 config = dev->actconfig;
328 if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
329 err = usb_reset_configuration(dev);
330 if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
331 snd_printdd("extigy_boot: new boot length = %d\n",
332 le16_to_cpu(get_cfg_desc(config)->wTotalLength));
333 return -ENODEV; /* quit this anyway */
334 }
335 return 0;
336}
337
338static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
339{
340 u8 buf = 1;
341
342 snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
343 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
344 0, 0, &buf, 1, 1000);
345 if (buf == 0) {
346 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
347 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
348 1, 2000, NULL, 0, 1000);
349 return -ENODEV;
350 }
351 return 0;
352}
353
354/*
355 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
356 * documented in the device's data sheet.
357 */
358static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
359{
360 u8 buf[4];
361 buf[0] = 0x20;
362 buf[1] = value & 0xff;
363 buf[2] = (value >> 8) & 0xff;
364 buf[3] = reg;
365 return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
366 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
367 0, 0, &buf, 4, 1000);
368}
369
370static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
371{
372 /*
373 * Enable line-out driver mode, set headphone source to front
374 * channels, enable stereo mic.
375 */
376 return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
377}
378
379/*
380 * C-Media CM6206 is based on CM106 with two additional
381 * registers that are not documented in the data sheet.
382 * Values here are chosen based on sniffing USB traffic
383 * under Windows.
384 */
385static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
386{
387 int err, reg;
388 int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
389
390 for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
391 err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
392 if (err < 0)
393 return err;
394 }
395
396 return err;
397}
398
399/*
400 * This call will put the synth in "USB send" mode, i.e it will send MIDI
401 * messages through USB (this is disabled at startup). The synth will
402 * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
403 * sign on its LCD. Values here are chosen based on sniffing USB traffic
404 * under Windows.
405 */
406static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
407{
408 int err, actual_length;
409
410 /* "midi send" enable */
411 static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
412
413 void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
414 if (!buf)
415 return -ENOMEM;
416 err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
417 ARRAY_SIZE(seq), &actual_length, 1000);
418 kfree(buf);
419 if (err < 0)
420 return err;
421
422 return 0;
423}
424
425/*
426 * Setup quirks
427 */
428#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
429#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
430#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
431#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
432#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
433#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
434#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
435#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
436#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
437#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
438
439static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
440 int iface,
441 int altno)
442{
443 /* Reset ALL ifaces to 0 altsetting.
444 * Call it for every possible altsetting of every interface.
445 */
446 usb_set_interface(chip->dev, iface, 0);
447
448 if (chip->setup & AUDIOPHILE_SET) {
449 if ((chip->setup & AUDIOPHILE_SET_DTS)
450 && altno != 6)
451 return 1; /* skip this altsetting */
452 if ((chip->setup & AUDIOPHILE_SET_96K)
453 && altno != 1)
454 return 1; /* skip this altsetting */
455 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
456 AUDIOPHILE_SET_24B_48K_DI && altno != 2)
457 return 1; /* skip this altsetting */
458 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
459 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
460 return 1; /* skip this altsetting */
461 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
462 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
463 return 1; /* skip this altsetting */
464 if ((chip->setup & AUDIOPHILE_SET_MASK) ==
465 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
466 return 1; /* skip this altsetting */
467 }
468
469 return 0; /* keep this altsetting */
470}
471
472int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
473 int iface,
474 int altno)
475{
476 /* audiophile usb: skip altsets incompatible with device_setup */
477 if (chip->usb_id == USB_ID(0x0763, 0x2003))
478 return audiophile_skip_setting_quirk(chip, iface, altno);
479
480 return 0;
481}
482
483int snd_usb_apply_boot_quirk(struct usb_device *dev,
484 struct usb_interface *intf,
485 const struct snd_usb_audio_quirk *quirk)
486{
487 u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
488 le16_to_cpu(dev->descriptor.idProduct));
489
490 /* SB Extigy needs special boot-up sequence */
491 /* if more models come, this will go to the quirk list. */
492 if (id == USB_ID(0x041e, 0x3000))
493 return snd_usb_extigy_boot_quirk(dev, intf);
494
495 /* SB Audigy 2 NX needs its own boot-up magic, too */
496 if (id == USB_ID(0x041e, 0x3020))
497 return snd_usb_audigy2nx_boot_quirk(dev);
498
499 /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
500 if (id == USB_ID(0x10f5, 0x0200))
501 return snd_usb_cm106_boot_quirk(dev);
502
503 /* C-Media CM6206 / CM106-Like Sound Device */
504 if (id == USB_ID(0x0d8c, 0x0102))
505 return snd_usb_cm6206_boot_quirk(dev);
506
507 /* Access Music VirusTI Desktop */
508 if (id == USB_ID(0x133e, 0x0815))
509 return snd_usb_accessmusic_boot_quirk(dev);
510
511 return 0;
512}
513
514/*
515 * check if the device uses big-endian samples
516 */
517int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
518{
519 switch (chip->usb_id) {
520 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
521 if (fp->endpoint & USB_DIR_IN)
522 return 1;
523 break;
524 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
525 if (chip->setup == 0x00 ||
526 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
527 return 1;
528 }
529 return 0;
530}
531
532/*
533 * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
534 * not for interface.
535 */
536
537enum {
538 EMU_QUIRK_SR_44100HZ = 0,
539 EMU_QUIRK_SR_48000HZ,
540 EMU_QUIRK_SR_88200HZ,
541 EMU_QUIRK_SR_96000HZ,
542 EMU_QUIRK_SR_176400HZ,
543 EMU_QUIRK_SR_192000HZ
544};
545
546static void set_format_emu_quirk(struct snd_usb_substream *subs,
547 struct audioformat *fmt)
548{
549 unsigned char emu_samplerate_id = 0;
550
551 /* When capture is active
552 * sample rate shouldn't be changed
553 * by playback substream
554 */
555 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
556 if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
557 return;
558 }
559
560 switch (fmt->rate_min) {
561 case 48000:
562 emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
563 break;
564 case 88200:
565 emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
566 break;
567 case 96000:
568 emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
569 break;
570 case 176400:
571 emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
572 break;
573 case 192000:
574 emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
575 break;
576 default:
577 emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
578 break;
579 }
580 snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
581}
582
583void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
584 struct audioformat *fmt)
585{
586 switch (subs->stream->chip->usb_id) {
587 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
588 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
589 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
590 set_format_emu_quirk(subs, fmt);
591 break;
592 }
593}
594
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
new file mode 100644
index 000000000000..03e5e94098cd
--- /dev/null
+++ b/sound/usb/quirks.h
@@ -0,0 +1,23 @@
1#ifndef __USBAUDIO_QUIRKS_H
2#define __USBAUDIO_QUIRKS_H
3
4int snd_usb_create_quirk(struct snd_usb_audio *chip,
5 struct usb_interface *iface,
6 struct usb_driver *driver,
7 const struct snd_usb_audio_quirk *quirk);
8
9int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
10 int iface,
11 int altno);
12
13int snd_usb_apply_boot_quirk(struct usb_device *dev,
14 struct usb_interface *intf,
15 const struct snd_usb_audio_quirk *quirk);
16
17void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
18 struct audioformat *fmt);
19
20int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
21 struct audioformat *fp);
22
23#endif /* __USBAUDIO_QUIRKS_H */
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
new file mode 100644
index 000000000000..de607d4411ac
--- /dev/null
+++ b/sound/usb/urb.c
@@ -0,0 +1,995 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 *
16 */
17
18#include <linux/gfp.h>
19#include <linux/init.h>
20#include <linux/usb.h>
21#include <linux/usb/audio.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25
26#include "usbaudio.h"
27#include "helper.h"
28#include "card.h"
29#include "urb.h"
30#include "pcm.h"
31
32/*
33 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
34 * this will overflow at approx 524 kHz
35 */
36static inline unsigned get_usb_full_speed_rate(unsigned int rate)
37{
38 return ((rate << 13) + 62) / 125;
39}
40
41/*
42 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
43 * this will overflow at approx 4 MHz
44 */
45static inline unsigned get_usb_high_speed_rate(unsigned int rate)
46{
47 return ((rate << 10) + 62) / 125;
48}
49
50/*
51 * unlink active urbs.
52 */
53static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
54{
55 struct snd_usb_audio *chip = subs->stream->chip;
56 unsigned int i;
57 int async;
58
59 subs->running = 0;
60
61 if (!force && subs->stream->chip->shutdown) /* to be sure... */
62 return -EBADFD;
63
64 async = !can_sleep && chip->async_unlink;
65
66 if (!async && in_interrupt())
67 return 0;
68
69 for (i = 0; i < subs->nurbs; i++) {
70 if (test_bit(i, &subs->active_mask)) {
71 if (!test_and_set_bit(i, &subs->unlink_mask)) {
72 struct urb *u = subs->dataurb[i].urb;
73 if (async)
74 usb_unlink_urb(u);
75 else
76 usb_kill_urb(u);
77 }
78 }
79 }
80 if (subs->syncpipe) {
81 for (i = 0; i < SYNC_URBS; i++) {
82 if (test_bit(i+16, &subs->active_mask)) {
83 if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
84 struct urb *u = subs->syncurb[i].urb;
85 if (async)
86 usb_unlink_urb(u);
87 else
88 usb_kill_urb(u);
89 }
90 }
91 }
92 }
93 return 0;
94}
95
96
97/*
98 * release a urb data
99 */
100static void release_urb_ctx(struct snd_urb_ctx *u)
101{
102 if (u->urb) {
103 if (u->buffer_size)
104 usb_free_coherent(u->subs->dev, u->buffer_size,
105 u->urb->transfer_buffer,
106 u->urb->transfer_dma);
107 usb_free_urb(u->urb);
108 u->urb = NULL;
109 }
110}
111
112/*
113 * wait until all urbs are processed.
114 */
115static int wait_clear_urbs(struct snd_usb_substream *subs)
116{
117 unsigned long end_time = jiffies + msecs_to_jiffies(1000);
118 unsigned int i;
119 int alive;
120
121 do {
122 alive = 0;
123 for (i = 0; i < subs->nurbs; i++) {
124 if (test_bit(i, &subs->active_mask))
125 alive++;
126 }
127 if (subs->syncpipe) {
128 for (i = 0; i < SYNC_URBS; i++) {
129 if (test_bit(i + 16, &subs->active_mask))
130 alive++;
131 }
132 }
133 if (! alive)
134 break;
135 schedule_timeout_uninterruptible(1);
136 } while (time_before(jiffies, end_time));
137 if (alive)
138 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
139 return 0;
140}
141
142/*
143 * release a substream
144 */
145void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
146{
147 int i;
148
149 /* stop urbs (to be sure) */
150 deactivate_urbs(subs, force, 1);
151 wait_clear_urbs(subs);
152
153 for (i = 0; i < MAX_URBS; i++)
154 release_urb_ctx(&subs->dataurb[i]);
155 for (i = 0; i < SYNC_URBS; i++)
156 release_urb_ctx(&subs->syncurb[i]);
157 usb_free_coherent(subs->dev, SYNC_URBS * 4,
158 subs->syncbuf, subs->sync_dma);
159 subs->syncbuf = NULL;
160 subs->nurbs = 0;
161}
162
163/*
164 * complete callback from data urb
165 */
166static void snd_complete_urb(struct urb *urb)
167{
168 struct snd_urb_ctx *ctx = urb->context;
169 struct snd_usb_substream *subs = ctx->subs;
170 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
171 int err = 0;
172
173 if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
174 !subs->running || /* can be stopped during retire callback */
175 (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
176 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
177 clear_bit(ctx->index, &subs->active_mask);
178 if (err < 0) {
179 snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
180 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
181 }
182 }
183}
184
185
186/*
187 * complete callback from sync urb
188 */
189static void snd_complete_sync_urb(struct urb *urb)
190{
191 struct snd_urb_ctx *ctx = urb->context;
192 struct snd_usb_substream *subs = ctx->subs;
193 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
194 int err = 0;
195
196 if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
197 !subs->running || /* can be stopped during retire callback */
198 (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
199 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
200 clear_bit(ctx->index + 16, &subs->active_mask);
201 if (err < 0) {
202 snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
203 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
204 }
205 }
206}
207
208
209/*
210 * initialize a substream for plaback/capture
211 */
212int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
213 unsigned int period_bytes,
214 unsigned int rate,
215 unsigned int frame_bits)
216{
217 unsigned int maxsize, i;
218 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
219 unsigned int urb_packs, total_packs, packs_per_ms;
220 struct snd_usb_audio *chip = subs->stream->chip;
221
222 /* calculate the frequency in 16.16 format */
223 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
224 subs->freqn = get_usb_full_speed_rate(rate);
225 else
226 subs->freqn = get_usb_high_speed_rate(rate);
227 subs->freqm = subs->freqn;
228 /* calculate max. frequency */
229 if (subs->maxpacksize) {
230 /* whatever fits into a max. size packet */
231 maxsize = subs->maxpacksize;
232 subs->freqmax = (maxsize / (frame_bits >> 3))
233 << (16 - subs->datainterval);
234 } else {
235 /* no max. packet size: just take 25% higher than nominal */
236 subs->freqmax = subs->freqn + (subs->freqn >> 2);
237 maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
238 >> (16 - subs->datainterval);
239 }
240 subs->phase = 0;
241
242 if (subs->fill_max)
243 subs->curpacksize = subs->maxpacksize;
244 else
245 subs->curpacksize = maxsize;
246
247 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
248 packs_per_ms = 8 >> subs->datainterval;
249 else
250 packs_per_ms = 1;
251
252 if (is_playback) {
253 urb_packs = max(chip->nrpacks, 1);
254 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
255 } else
256 urb_packs = 1;
257 urb_packs *= packs_per_ms;
258 if (subs->syncpipe)
259 urb_packs = min(urb_packs, 1U << subs->syncinterval);
260
261 /* decide how many packets to be used */
262 if (is_playback) {
263 unsigned int minsize, maxpacks;
264 /* determine how small a packet can be */
265 minsize = (subs->freqn >> (16 - subs->datainterval))
266 * (frame_bits >> 3);
267 /* with sync from device, assume it can be 12% lower */
268 if (subs->syncpipe)
269 minsize -= minsize >> 3;
270 minsize = max(minsize, 1u);
271 total_packs = (period_bytes + minsize - 1) / minsize;
272 /* we need at least two URBs for queueing */
273 if (total_packs < 2) {
274 total_packs = 2;
275 } else {
276 /* and we don't want too long a queue either */
277 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
278 total_packs = min(total_packs, maxpacks);
279 }
280 } else {
281 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
282 urb_packs >>= 1;
283 total_packs = MAX_URBS * urb_packs;
284 }
285 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
286 if (subs->nurbs > MAX_URBS) {
287 /* too much... */
288 subs->nurbs = MAX_URBS;
289 total_packs = MAX_URBS * urb_packs;
290 } else if (subs->nurbs < 2) {
291 /* too little - we need at least two packets
292 * to ensure contiguous playback/capture
293 */
294 subs->nurbs = 2;
295 }
296
297 /* allocate and initialize data urbs */
298 for (i = 0; i < subs->nurbs; i++) {
299 struct snd_urb_ctx *u = &subs->dataurb[i];
300 u->index = i;
301 u->subs = subs;
302 u->packets = (i + 1) * total_packs / subs->nurbs
303 - i * total_packs / subs->nurbs;
304 u->buffer_size = maxsize * u->packets;
305 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
306 u->packets++; /* for transfer delimiter */
307 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
308 if (!u->urb)
309 goto out_of_memory;
310 u->urb->transfer_buffer =
311 usb_alloc_coherent(subs->dev, u->buffer_size,
312 GFP_KERNEL, &u->urb->transfer_dma);
313 if (!u->urb->transfer_buffer)
314 goto out_of_memory;
315 u->urb->pipe = subs->datapipe;
316 u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
317 u->urb->interval = 1 << subs->datainterval;
318 u->urb->context = u;
319 u->urb->complete = snd_complete_urb;
320 }
321
322 if (subs->syncpipe) {
323 /* allocate and initialize sync urbs */
324 subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
325 GFP_KERNEL, &subs->sync_dma);
326 if (!subs->syncbuf)
327 goto out_of_memory;
328 for (i = 0; i < SYNC_URBS; i++) {
329 struct snd_urb_ctx *u = &subs->syncurb[i];
330 u->index = i;
331 u->subs = subs;
332 u->packets = 1;
333 u->urb = usb_alloc_urb(1, GFP_KERNEL);
334 if (!u->urb)
335 goto out_of_memory;
336 u->urb->transfer_buffer = subs->syncbuf + i * 4;
337 u->urb->transfer_dma = subs->sync_dma + i * 4;
338 u->urb->transfer_buffer_length = 4;
339 u->urb->pipe = subs->syncpipe;
340 u->urb->transfer_flags = URB_ISO_ASAP |
341 URB_NO_TRANSFER_DMA_MAP;
342 u->urb->number_of_packets = 1;
343 u->urb->interval = 1 << subs->syncinterval;
344 u->urb->context = u;
345 u->urb->complete = snd_complete_sync_urb;
346 }
347 }
348 return 0;
349
350out_of_memory:
351 snd_usb_release_substream_urbs(subs, 0);
352 return -ENOMEM;
353}
354
355/*
356 * prepare urb for full speed capture sync pipe
357 *
358 * fill the length and offset of each urb descriptor.
359 * the fixed 10.14 frequency is passed through the pipe.
360 */
361static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
362 struct snd_pcm_runtime *runtime,
363 struct urb *urb)
364{
365 unsigned char *cp = urb->transfer_buffer;
366 struct snd_urb_ctx *ctx = urb->context;
367
368 urb->dev = ctx->subs->dev; /* we need to set this at each time */
369 urb->iso_frame_desc[0].length = 3;
370 urb->iso_frame_desc[0].offset = 0;
371 cp[0] = subs->freqn >> 2;
372 cp[1] = subs->freqn >> 10;
373 cp[2] = subs->freqn >> 18;
374 return 0;
375}
376
377/*
378 * prepare urb for high speed capture sync pipe
379 *
380 * fill the length and offset of each urb descriptor.
381 * the fixed 12.13 frequency is passed as 16.16 through the pipe.
382 */
383static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
384 struct snd_pcm_runtime *runtime,
385 struct urb *urb)
386{
387 unsigned char *cp = urb->transfer_buffer;
388 struct snd_urb_ctx *ctx = urb->context;
389
390 urb->dev = ctx->subs->dev; /* we need to set this at each time */
391 urb->iso_frame_desc[0].length = 4;
392 urb->iso_frame_desc[0].offset = 0;
393 cp[0] = subs->freqn;
394 cp[1] = subs->freqn >> 8;
395 cp[2] = subs->freqn >> 16;
396 cp[3] = subs->freqn >> 24;
397 return 0;
398}
399
400/*
401 * process after capture sync complete
402 * - nothing to do
403 */
404static int retire_capture_sync_urb(struct snd_usb_substream *subs,
405 struct snd_pcm_runtime *runtime,
406 struct urb *urb)
407{
408 return 0;
409}
410
411/*
412 * prepare urb for capture data pipe
413 *
414 * fill the offset and length of each descriptor.
415 *
416 * we use a temporary buffer to write the captured data.
417 * since the length of written data is determined by host, we cannot
418 * write onto the pcm buffer directly... the data is thus copied
419 * later at complete callback to the global buffer.
420 */
421static int prepare_capture_urb(struct snd_usb_substream *subs,
422 struct snd_pcm_runtime *runtime,
423 struct urb *urb)
424{
425 int i, offs;
426 struct snd_urb_ctx *ctx = urb->context;
427
428 offs = 0;
429 urb->dev = ctx->subs->dev; /* we need to set this at each time */
430 for (i = 0; i < ctx->packets; i++) {
431 urb->iso_frame_desc[i].offset = offs;
432 urb->iso_frame_desc[i].length = subs->curpacksize;
433 offs += subs->curpacksize;
434 }
435 urb->transfer_buffer_length = offs;
436 urb->number_of_packets = ctx->packets;
437 return 0;
438}
439
440/*
441 * process after capture complete
442 *
443 * copy the data from each desctiptor to the pcm buffer, and
444 * update the current position.
445 */
446static int retire_capture_urb(struct snd_usb_substream *subs,
447 struct snd_pcm_runtime *runtime,
448 struct urb *urb)
449{
450 unsigned long flags;
451 unsigned char *cp;
452 int i;
453 unsigned int stride, frames, bytes, oldptr;
454 int period_elapsed = 0;
455
456 stride = runtime->frame_bits >> 3;
457
458 for (i = 0; i < urb->number_of_packets; i++) {
459 cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
460 if (urb->iso_frame_desc[i].status) {
461 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
462 // continue;
463 }
464 bytes = urb->iso_frame_desc[i].actual_length;
465 frames = bytes / stride;
466 if (!subs->txfr_quirk)
467 bytes = frames * stride;
468 if (bytes % (runtime->sample_bits >> 3) != 0) {
469#ifdef CONFIG_SND_DEBUG_VERBOSE
470 int oldbytes = bytes;
471#endif
472 bytes = frames * stride;
473 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
474 oldbytes, bytes);
475 }
476 /* update the current pointer */
477 spin_lock_irqsave(&subs->lock, flags);
478 oldptr = subs->hwptr_done;
479 subs->hwptr_done += bytes;
480 if (subs->hwptr_done >= runtime->buffer_size * stride)
481 subs->hwptr_done -= runtime->buffer_size * stride;
482 frames = (bytes + (oldptr % stride)) / stride;
483 subs->transfer_done += frames;
484 if (subs->transfer_done >= runtime->period_size) {
485 subs->transfer_done -= runtime->period_size;
486 period_elapsed = 1;
487 }
488 spin_unlock_irqrestore(&subs->lock, flags);
489 /* copy a data chunk */
490 if (oldptr + bytes > runtime->buffer_size * stride) {
491 unsigned int bytes1 =
492 runtime->buffer_size * stride - oldptr;
493 memcpy(runtime->dma_area + oldptr, cp, bytes1);
494 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
495 } else {
496 memcpy(runtime->dma_area + oldptr, cp, bytes);
497 }
498 }
499 if (period_elapsed)
500 snd_pcm_period_elapsed(subs->pcm_substream);
501 return 0;
502}
503
504/*
505 * Process after capture complete when paused. Nothing to do.
506 */
507static int retire_paused_capture_urb(struct snd_usb_substream *subs,
508 struct snd_pcm_runtime *runtime,
509 struct urb *urb)
510{
511 return 0;
512}
513
514
515/*
516 * prepare urb for full speed playback sync pipe
517 *
518 * set up the offset and length to receive the current frequency.
519 */
520
521static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
522 struct snd_pcm_runtime *runtime,
523 struct urb *urb)
524{
525 struct snd_urb_ctx *ctx = urb->context;
526
527 urb->dev = ctx->subs->dev; /* we need to set this at each time */
528 urb->iso_frame_desc[0].length = 3;
529 urb->iso_frame_desc[0].offset = 0;
530 return 0;
531}
532
533/*
534 * prepare urb for high speed playback sync pipe
535 *
536 * set up the offset and length to receive the current frequency.
537 */
538
539static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
540 struct snd_pcm_runtime *runtime,
541 struct urb *urb)
542{
543 struct snd_urb_ctx *ctx = urb->context;
544
545 urb->dev = ctx->subs->dev; /* we need to set this at each time */
546 urb->iso_frame_desc[0].length = 4;
547 urb->iso_frame_desc[0].offset = 0;
548 return 0;
549}
550
551/*
552 * process after full speed playback sync complete
553 *
554 * retrieve the current 10.14 frequency from pipe, and set it.
555 * the value is referred in prepare_playback_urb().
556 */
557static int retire_playback_sync_urb(struct snd_usb_substream *subs,
558 struct snd_pcm_runtime *runtime,
559 struct urb *urb)
560{
561 unsigned int f;
562 unsigned long flags;
563
564 if (urb->iso_frame_desc[0].status == 0 &&
565 urb->iso_frame_desc[0].actual_length == 3) {
566 f = combine_triple((u8*)urb->transfer_buffer) << 2;
567 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
568 spin_lock_irqsave(&subs->lock, flags);
569 subs->freqm = f;
570 spin_unlock_irqrestore(&subs->lock, flags);
571 }
572 }
573
574 return 0;
575}
576
577/*
578 * process after high speed playback sync complete
579 *
580 * retrieve the current 12.13 frequency from pipe, and set it.
581 * the value is referred in prepare_playback_urb().
582 */
583static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
584 struct snd_pcm_runtime *runtime,
585 struct urb *urb)
586{
587 unsigned int f;
588 unsigned long flags;
589
590 if (urb->iso_frame_desc[0].status == 0 &&
591 urb->iso_frame_desc[0].actual_length == 4) {
592 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
593 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
594 spin_lock_irqsave(&subs->lock, flags);
595 subs->freqm = f;
596 spin_unlock_irqrestore(&subs->lock, flags);
597 }
598 }
599
600 return 0;
601}
602
603/*
604 * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
605 *
606 * These devices return the number of samples per packet instead of the number
607 * of samples per microframe.
608 */
609static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
610 struct snd_pcm_runtime *runtime,
611 struct urb *urb)
612{
613 unsigned int f;
614 unsigned long flags;
615
616 if (urb->iso_frame_desc[0].status == 0 &&
617 urb->iso_frame_desc[0].actual_length == 4) {
618 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
619 f >>= subs->datainterval;
620 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
621 spin_lock_irqsave(&subs->lock, flags);
622 subs->freqm = f;
623 spin_unlock_irqrestore(&subs->lock, flags);
624 }
625 }
626
627 return 0;
628}
629
630/* determine the number of frames in the next packet */
631static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
632{
633 if (subs->fill_max)
634 return subs->maxframesize;
635 else {
636 subs->phase = (subs->phase & 0xffff)
637 + (subs->freqm << subs->datainterval);
638 return min(subs->phase >> 16, subs->maxframesize);
639 }
640}
641
642/*
643 * Prepare urb for streaming before playback starts or when paused.
644 *
645 * We don't have any data, so we send silence.
646 */
647static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
648 struct snd_pcm_runtime *runtime,
649 struct urb *urb)
650{
651 unsigned int i, offs, counts;
652 struct snd_urb_ctx *ctx = urb->context;
653 int stride = runtime->frame_bits >> 3;
654
655 offs = 0;
656 urb->dev = ctx->subs->dev;
657 for (i = 0; i < ctx->packets; ++i) {
658 counts = snd_usb_audio_next_packet_size(subs);
659 urb->iso_frame_desc[i].offset = offs * stride;
660 urb->iso_frame_desc[i].length = counts * stride;
661 offs += counts;
662 }
663 urb->number_of_packets = ctx->packets;
664 urb->transfer_buffer_length = offs * stride;
665 memset(urb->transfer_buffer,
666 runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
667 offs * stride);
668 return 0;
669}
670
671/*
672 * prepare urb for playback data pipe
673 *
674 * Since a URB can handle only a single linear buffer, we must use double
675 * buffering when the data to be transferred overflows the buffer boundary.
676 * To avoid inconsistencies when updating hwptr_done, we use double buffering
677 * for all URBs.
678 */
679static int prepare_playback_urb(struct snd_usb_substream *subs,
680 struct snd_pcm_runtime *runtime,
681 struct urb *urb)
682{
683 int i, stride;
684 unsigned int counts, frames, bytes;
685 unsigned long flags;
686 int period_elapsed = 0;
687 struct snd_urb_ctx *ctx = urb->context;
688
689 stride = runtime->frame_bits >> 3;
690
691 frames = 0;
692 urb->dev = ctx->subs->dev; /* we need to set this at each time */
693 urb->number_of_packets = 0;
694 spin_lock_irqsave(&subs->lock, flags);
695 for (i = 0; i < ctx->packets; i++) {
696 counts = snd_usb_audio_next_packet_size(subs);
697 /* set up descriptor */
698 urb->iso_frame_desc[i].offset = frames * stride;
699 urb->iso_frame_desc[i].length = counts * stride;
700 frames += counts;
701 urb->number_of_packets++;
702 subs->transfer_done += counts;
703 if (subs->transfer_done >= runtime->period_size) {
704 subs->transfer_done -= runtime->period_size;
705 period_elapsed = 1;
706 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
707 if (subs->transfer_done > 0) {
708 /* FIXME: fill-max mode is not
709 * supported yet */
710 frames -= subs->transfer_done;
711 counts -= subs->transfer_done;
712 urb->iso_frame_desc[i].length =
713 counts * stride;
714 subs->transfer_done = 0;
715 }
716 i++;
717 if (i < ctx->packets) {
718 /* add a transfer delimiter */
719 urb->iso_frame_desc[i].offset =
720 frames * stride;
721 urb->iso_frame_desc[i].length = 0;
722 urb->number_of_packets++;
723 }
724 break;
725 }
726 }
727 if (period_elapsed) /* finish at the period boundary */
728 break;
729 }
730 bytes = frames * stride;
731 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
732 /* err, the transferred area goes over buffer boundary. */
733 unsigned int bytes1 =
734 runtime->buffer_size * stride - subs->hwptr_done;
735 memcpy(urb->transfer_buffer,
736 runtime->dma_area + subs->hwptr_done, bytes1);
737 memcpy(urb->transfer_buffer + bytes1,
738 runtime->dma_area, bytes - bytes1);
739 } else {
740 memcpy(urb->transfer_buffer,
741 runtime->dma_area + subs->hwptr_done, bytes);
742 }
743 subs->hwptr_done += bytes;
744 if (subs->hwptr_done >= runtime->buffer_size * stride)
745 subs->hwptr_done -= runtime->buffer_size * stride;
746 runtime->delay += frames;
747 spin_unlock_irqrestore(&subs->lock, flags);
748 urb->transfer_buffer_length = bytes;
749 if (period_elapsed)
750 snd_pcm_period_elapsed(subs->pcm_substream);
751 return 0;
752}
753
754/*
755 * process after playback data complete
756 * - decrease the delay count again
757 */
758static int retire_playback_urb(struct snd_usb_substream *subs,
759 struct snd_pcm_runtime *runtime,
760 struct urb *urb)
761{
762 unsigned long flags;
763 int stride = runtime->frame_bits >> 3;
764 int processed = urb->transfer_buffer_length / stride;
765
766 spin_lock_irqsave(&subs->lock, flags);
767 if (processed > runtime->delay)
768 runtime->delay = 0;
769 else
770 runtime->delay -= processed;
771 spin_unlock_irqrestore(&subs->lock, flags);
772 return 0;
773}
774
775static const char *usb_error_string(int err)
776{
777 switch (err) {
778 case -ENODEV:
779 return "no device";
780 case -ENOENT:
781 return "endpoint not enabled";
782 case -EPIPE:
783 return "endpoint stalled";
784 case -ENOSPC:
785 return "not enough bandwidth";
786 case -ESHUTDOWN:
787 return "device disabled";
788 case -EHOSTUNREACH:
789 return "device suspended";
790 case -EINVAL:
791 case -EAGAIN:
792 case -EFBIG:
793 case -EMSGSIZE:
794 return "internal error";
795 default:
796 return "unknown error";
797 }
798}
799
800/*
801 * set up and start data/sync urbs
802 */
803static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
804{
805 unsigned int i;
806 int err;
807
808 if (subs->stream->chip->shutdown)
809 return -EBADFD;
810
811 for (i = 0; i < subs->nurbs; i++) {
812 if (snd_BUG_ON(!subs->dataurb[i].urb))
813 return -EINVAL;
814 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
815 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
816 goto __error;
817 }
818 }
819 if (subs->syncpipe) {
820 for (i = 0; i < SYNC_URBS; i++) {
821 if (snd_BUG_ON(!subs->syncurb[i].urb))
822 return -EINVAL;
823 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
824 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
825 goto __error;
826 }
827 }
828 }
829
830 subs->active_mask = 0;
831 subs->unlink_mask = 0;
832 subs->running = 1;
833 for (i = 0; i < subs->nurbs; i++) {
834 err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
835 if (err < 0) {
836 snd_printk(KERN_ERR "cannot submit datapipe "
837 "for urb %d, error %d: %s\n",
838 i, err, usb_error_string(err));
839 goto __error;
840 }
841 set_bit(i, &subs->active_mask);
842 }
843 if (subs->syncpipe) {
844 for (i = 0; i < SYNC_URBS; i++) {
845 err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
846 if (err < 0) {
847 snd_printk(KERN_ERR "cannot submit syncpipe "
848 "for urb %d, error %d: %s\n",
849 i, err, usb_error_string(err));
850 goto __error;
851 }
852 set_bit(i + 16, &subs->active_mask);
853 }
854 }
855 return 0;
856
857 __error:
858 // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
859 deactivate_urbs(subs, 0, 0);
860 return -EPIPE;
861}
862
863
864/*
865 */
866static struct snd_urb_ops audio_urb_ops[2] = {
867 {
868 .prepare = prepare_nodata_playback_urb,
869 .retire = retire_playback_urb,
870 .prepare_sync = prepare_playback_sync_urb,
871 .retire_sync = retire_playback_sync_urb,
872 },
873 {
874 .prepare = prepare_capture_urb,
875 .retire = retire_capture_urb,
876 .prepare_sync = prepare_capture_sync_urb,
877 .retire_sync = retire_capture_sync_urb,
878 },
879};
880
881static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
882 {
883 .prepare = prepare_nodata_playback_urb,
884 .retire = retire_playback_urb,
885 .prepare_sync = prepare_playback_sync_urb_hs,
886 .retire_sync = retire_playback_sync_urb_hs,
887 },
888 {
889 .prepare = prepare_capture_urb,
890 .retire = retire_capture_urb,
891 .prepare_sync = prepare_capture_sync_urb_hs,
892 .retire_sync = retire_capture_sync_urb,
893 },
894};
895
896/*
897 * initialize the substream instance.
898 */
899
900void snd_usb_init_substream(struct snd_usb_stream *as,
901 int stream, struct audioformat *fp)
902{
903 struct snd_usb_substream *subs = &as->substream[stream];
904
905 INIT_LIST_HEAD(&subs->fmt_list);
906 spin_lock_init(&subs->lock);
907
908 subs->stream = as;
909 subs->direction = stream;
910 subs->dev = as->chip->dev;
911 subs->txfr_quirk = as->chip->txfr_quirk;
912 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
913 subs->ops = audio_urb_ops[stream];
914 } else {
915 subs->ops = audio_urb_ops_high_speed[stream];
916 switch (as->chip->usb_id) {
917 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
918 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
919 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
920 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
921 break;
922 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
923 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
924 subs->ops.prepare_sync = prepare_playback_sync_urb;
925 subs->ops.retire_sync = retire_playback_sync_urb;
926 break;
927 }
928 }
929
930 snd_usb_set_pcm_ops(as->pcm, stream);
931
932 list_add_tail(&fp->list, &subs->fmt_list);
933 subs->formats |= fp->formats;
934 subs->endpoint = fp->endpoint;
935 subs->num_formats++;
936 subs->fmt_type = fp->fmt_type;
937}
938
939int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd)
940{
941 struct snd_usb_substream *subs = substream->runtime->private_data;
942
943 switch (cmd) {
944 case SNDRV_PCM_TRIGGER_START:
945 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
946 subs->ops.prepare = prepare_playback_urb;
947 return 0;
948 case SNDRV_PCM_TRIGGER_STOP:
949 return deactivate_urbs(subs, 0, 0);
950 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
951 subs->ops.prepare = prepare_nodata_playback_urb;
952 return 0;
953 }
954
955 return -EINVAL;
956}
957
958int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
959{
960 struct snd_usb_substream *subs = substream->runtime->private_data;
961
962 switch (cmd) {
963 case SNDRV_PCM_TRIGGER_START:
964 subs->ops.retire = retire_capture_urb;
965 return start_urbs(subs, substream->runtime);
966 case SNDRV_PCM_TRIGGER_STOP:
967 return deactivate_urbs(subs, 0, 0);
968 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
969 subs->ops.retire = retire_paused_capture_urb;
970 return 0;
971 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
972 subs->ops.retire = retire_capture_urb;
973 return 0;
974 }
975
976 return -EINVAL;
977}
978
979int snd_usb_substream_prepare(struct snd_usb_substream *subs,
980 struct snd_pcm_runtime *runtime)
981{
982 /* clear urbs (to be sure) */
983 deactivate_urbs(subs, 0, 1);
984 wait_clear_urbs(subs);
985
986 /* for playback, submit the URBs now; otherwise, the first hwptr_done
987 * updates for all URBs would happen at the same time when starting */
988 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
989 subs->ops.prepare = prepare_nodata_playback_urb;
990 return start_urbs(subs, runtime);
991 }
992
993 return 0;
994}
995
diff --git a/sound/usb/urb.h b/sound/usb/urb.h
new file mode 100644
index 000000000000..888da38079cf
--- /dev/null
+++ b/sound/usb/urb.h
@@ -0,0 +1,21 @@
1#ifndef __USBAUDIO_URB_H
2#define __USBAUDIO_URB_H
3
4void snd_usb_init_substream(struct snd_usb_stream *as,
5 int stream,
6 struct audioformat *fp);
7
8int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
9 unsigned int period_bytes,
10 unsigned int rate,
11 unsigned int frame_bits);
12
13void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force);
14
15int snd_usb_substream_prepare(struct snd_usb_substream *subs,
16 struct snd_pcm_runtime *runtime);
17
18int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd);
19int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd);
20
21#endif /* __USBAUDIO_URB_H */
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
deleted file mode 100644
index 9d2274ce01d5..000000000000
--- a/sound/usb/usbaudio.c
+++ /dev/null
@@ -1,4050 +0,0 @@
1/*
2 * (Tentative) USB Audio Driver for ALSA
3 *
4 * Main and PCM part
5 *
6 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
7 *
8 * Many codes borrowed from audio.c by
9 * Alan Cox (alan@lxorguk.ukuu.org.uk)
10 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 *
28 * NOTES:
29 *
30 * - async unlink should be used for avoiding the sleep inside lock.
31 * 2.4.22 usb-uhci seems buggy for async unlinking and results in
32 * oops. in such a cse, pass async_unlink=0 option.
33 * - the linked URBs would be preferred but not used so far because of
34 * the instability of unlinking.
35 * - type II is not supported properly. there is no device which supports
36 * this type *correctly*. SB extigy looks as if it supports, but it's
37 * indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
38 */
39
40
41#include <linux/bitops.h>
42#include <linux/init.h>
43#include <linux/list.h>
44#include <linux/slab.h>
45#include <linux/string.h>
46#include <linux/usb.h>
47#include <linux/moduleparam.h>
48#include <linux/mutex.h>
49#include <linux/usb/audio.h>
50#include <linux/usb/ch9.h>
51
52#include <sound/core.h>
53#include <sound/info.h>
54#include <sound/pcm.h>
55#include <sound/pcm_params.h>
56#include <sound/initval.h>
57
58#include "usbaudio.h"
59
60
61MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
62MODULE_DESCRIPTION("USB Audio");
63MODULE_LICENSE("GPL");
64MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
65
66
67static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
68static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
69static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
70/* Vendor/product IDs for this card */
71static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
72static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
73static int nrpacks = 8; /* max. number of packets per urb */
74static int async_unlink = 1;
75static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/
76static int ignore_ctl_error;
77
78module_param_array(index, int, NULL, 0444);
79MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
80module_param_array(id, charp, NULL, 0444);
81MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
82module_param_array(enable, bool, NULL, 0444);
83MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
84module_param_array(vid, int, NULL, 0444);
85MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
86module_param_array(pid, int, NULL, 0444);
87MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
88module_param(nrpacks, int, 0644);
89MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
90module_param(async_unlink, bool, 0444);
91MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
92module_param_array(device_setup, int, NULL, 0444);
93MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
94module_param(ignore_ctl_error, bool, 0444);
95MODULE_PARM_DESC(ignore_ctl_error,
96 "Ignore errors from USB controller for mixer interfaces.");
97
98/*
99 * debug the h/w constraints
100 */
101/* #define HW_CONST_DEBUG */
102
103
104/*
105 *
106 */
107
108#define MAX_PACKS 20
109#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
110#define MAX_URBS 8
111#define SYNC_URBS 4 /* always four urbs for sync */
112#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */
113
114struct audioformat {
115 struct list_head list;
116 snd_pcm_format_t format; /* format type */
117 unsigned int channels; /* # channels */
118 unsigned int fmt_type; /* USB audio format type (1-3) */
119 unsigned int frame_size; /* samples per frame for non-audio */
120 int iface; /* interface number */
121 unsigned char altsetting; /* corresponding alternate setting */
122 unsigned char altset_idx; /* array index of altenate setting */
123 unsigned char attributes; /* corresponding attributes of cs endpoint */
124 unsigned char endpoint; /* endpoint */
125 unsigned char ep_attr; /* endpoint attributes */
126 unsigned char datainterval; /* log_2 of data packet interval */
127 unsigned int maxpacksize; /* max. packet size */
128 unsigned int rates; /* rate bitmasks */
129 unsigned int rate_min, rate_max; /* min/max rates */
130 unsigned int nr_rates; /* number of rate table entries */
131 unsigned int *rate_table; /* rate table */
132};
133
134struct snd_usb_substream;
135
136struct snd_urb_ctx {
137 struct urb *urb;
138 unsigned int buffer_size; /* size of data buffer, if data URB */
139 struct snd_usb_substream *subs;
140 int index; /* index for urb array */
141 int packets; /* number of packets per urb */
142};
143
144struct snd_urb_ops {
145 int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
146 int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
147 int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
148 int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
149};
150
151struct snd_usb_substream {
152 struct snd_usb_stream *stream;
153 struct usb_device *dev;
154 struct snd_pcm_substream *pcm_substream;
155 int direction; /* playback or capture */
156 int interface; /* current interface */
157 int endpoint; /* assigned endpoint */
158 struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
159 unsigned int cur_rate; /* current rate (for hw_params callback) */
160 unsigned int period_bytes; /* current period bytes (for hw_params callback) */
161 unsigned int format; /* USB data format */
162 unsigned int datapipe; /* the data i/o pipe */
163 unsigned int syncpipe; /* 1 - async out or adaptive in */
164 unsigned int datainterval; /* log_2 of data packet interval */
165 unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
166 unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
167 unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
168 unsigned int freqmax; /* maximum sampling rate, used for buffer management */
169 unsigned int phase; /* phase accumulator */
170 unsigned int maxpacksize; /* max packet size in bytes */
171 unsigned int maxframesize; /* max packet size in frames */
172 unsigned int curpacksize; /* current packet size in bytes (for capture) */
173 unsigned int curframesize; /* current packet size in frames (for capture) */
174 unsigned int fill_max: 1; /* fill max packet size always */
175 unsigned int txfr_quirk:1; /* allow sub-frame alignment */
176 unsigned int fmt_type; /* USB audio format type (1-3) */
177
178 unsigned int running: 1; /* running status */
179
180 unsigned int hwptr_done; /* processed byte position in the buffer */
181 unsigned int transfer_done; /* processed frames since last period update */
182 unsigned long active_mask; /* bitmask of active urbs */
183 unsigned long unlink_mask; /* bitmask of unlinked urbs */
184
185 unsigned int nurbs; /* # urbs */
186 struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */
187 struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
188 char *syncbuf; /* sync buffer for all sync URBs */
189 dma_addr_t sync_dma; /* DMA address of syncbuf */
190
191 u64 formats; /* format bitmasks (all or'ed) */
192 unsigned int num_formats; /* number of supported audio formats (list) */
193 struct list_head fmt_list; /* format list */
194 struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
195 spinlock_t lock;
196
197 struct snd_urb_ops ops; /* callbacks (must be filled at init) */
198};
199
200
201struct snd_usb_stream {
202 struct snd_usb_audio *chip;
203 struct snd_pcm *pcm;
204 int pcm_index;
205 unsigned int fmt_type; /* USB audio format type (1-3) */
206 struct snd_usb_substream substream[2];
207 struct list_head list;
208};
209
210
211/*
212 * we keep the snd_usb_audio_t instances by ourselves for merging
213 * the all interfaces on the same card as one sound device.
214 */
215
216static DEFINE_MUTEX(register_mutex);
217static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
218
219
220/*
221 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
222 * this will overflow at approx 524 kHz
223 */
224static inline unsigned get_usb_full_speed_rate(unsigned int rate)
225{
226 return ((rate << 13) + 62) / 125;
227}
228
229/*
230 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
231 * this will overflow at approx 4 MHz
232 */
233static inline unsigned get_usb_high_speed_rate(unsigned int rate)
234{
235 return ((rate << 10) + 62) / 125;
236}
237
238/* convert our full speed USB rate into sampling rate in Hz */
239static inline unsigned get_full_speed_hz(unsigned int usb_rate)
240{
241 return (usb_rate * 125 + (1 << 12)) >> 13;
242}
243
244/* convert our high speed USB rate into sampling rate in Hz */
245static inline unsigned get_high_speed_hz(unsigned int usb_rate)
246{
247 return (usb_rate * 125 + (1 << 9)) >> 10;
248}
249
250
251/*
252 * prepare urb for full speed capture sync pipe
253 *
254 * fill the length and offset of each urb descriptor.
255 * the fixed 10.14 frequency is passed through the pipe.
256 */
257static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
258 struct snd_pcm_runtime *runtime,
259 struct urb *urb)
260{
261 unsigned char *cp = urb->transfer_buffer;
262 struct snd_urb_ctx *ctx = urb->context;
263
264 urb->dev = ctx->subs->dev; /* we need to set this at each time */
265 urb->iso_frame_desc[0].length = 3;
266 urb->iso_frame_desc[0].offset = 0;
267 cp[0] = subs->freqn >> 2;
268 cp[1] = subs->freqn >> 10;
269 cp[2] = subs->freqn >> 18;
270 return 0;
271}
272
273/*
274 * prepare urb for high speed capture sync pipe
275 *
276 * fill the length and offset of each urb descriptor.
277 * the fixed 12.13 frequency is passed as 16.16 through the pipe.
278 */
279static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
280 struct snd_pcm_runtime *runtime,
281 struct urb *urb)
282{
283 unsigned char *cp = urb->transfer_buffer;
284 struct snd_urb_ctx *ctx = urb->context;
285
286 urb->dev = ctx->subs->dev; /* we need to set this at each time */
287 urb->iso_frame_desc[0].length = 4;
288 urb->iso_frame_desc[0].offset = 0;
289 cp[0] = subs->freqn;
290 cp[1] = subs->freqn >> 8;
291 cp[2] = subs->freqn >> 16;
292 cp[3] = subs->freqn >> 24;
293 return 0;
294}
295
296/*
297 * process after capture sync complete
298 * - nothing to do
299 */
300static int retire_capture_sync_urb(struct snd_usb_substream *subs,
301 struct snd_pcm_runtime *runtime,
302 struct urb *urb)
303{
304 return 0;
305}
306
307/*
308 * prepare urb for capture data pipe
309 *
310 * fill the offset and length of each descriptor.
311 *
312 * we use a temporary buffer to write the captured data.
313 * since the length of written data is determined by host, we cannot
314 * write onto the pcm buffer directly... the data is thus copied
315 * later at complete callback to the global buffer.
316 */
317static int prepare_capture_urb(struct snd_usb_substream *subs,
318 struct snd_pcm_runtime *runtime,
319 struct urb *urb)
320{
321 int i, offs;
322 struct snd_urb_ctx *ctx = urb->context;
323
324 offs = 0;
325 urb->dev = ctx->subs->dev; /* we need to set this at each time */
326 for (i = 0; i < ctx->packets; i++) {
327 urb->iso_frame_desc[i].offset = offs;
328 urb->iso_frame_desc[i].length = subs->curpacksize;
329 offs += subs->curpacksize;
330 }
331 urb->transfer_buffer_length = offs;
332 urb->number_of_packets = ctx->packets;
333 return 0;
334}
335
336/*
337 * process after capture complete
338 *
339 * copy the data from each desctiptor to the pcm buffer, and
340 * update the current position.
341 */
342static int retire_capture_urb(struct snd_usb_substream *subs,
343 struct snd_pcm_runtime *runtime,
344 struct urb *urb)
345{
346 unsigned long flags;
347 unsigned char *cp;
348 int i;
349 unsigned int stride, frames, bytes, oldptr;
350 int period_elapsed = 0;
351
352 stride = runtime->frame_bits >> 3;
353
354 for (i = 0; i < urb->number_of_packets; i++) {
355 cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
356 if (urb->iso_frame_desc[i].status) {
357 snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
358 // continue;
359 }
360 bytes = urb->iso_frame_desc[i].actual_length;
361 frames = bytes / stride;
362 if (!subs->txfr_quirk)
363 bytes = frames * stride;
364 if (bytes % (runtime->sample_bits >> 3) != 0) {
365#ifdef CONFIG_SND_DEBUG_VERBOSE
366 int oldbytes = bytes;
367#endif
368 bytes = frames * stride;
369 snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
370 oldbytes, bytes);
371 }
372 /* update the current pointer */
373 spin_lock_irqsave(&subs->lock, flags);
374 oldptr = subs->hwptr_done;
375 subs->hwptr_done += bytes;
376 if (subs->hwptr_done >= runtime->buffer_size * stride)
377 subs->hwptr_done -= runtime->buffer_size * stride;
378 frames = (bytes + (oldptr % stride)) / stride;
379 subs->transfer_done += frames;
380 if (subs->transfer_done >= runtime->period_size) {
381 subs->transfer_done -= runtime->period_size;
382 period_elapsed = 1;
383 }
384 spin_unlock_irqrestore(&subs->lock, flags);
385 /* copy a data chunk */
386 if (oldptr + bytes > runtime->buffer_size * stride) {
387 unsigned int bytes1 =
388 runtime->buffer_size * stride - oldptr;
389 memcpy(runtime->dma_area + oldptr, cp, bytes1);
390 memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
391 } else {
392 memcpy(runtime->dma_area + oldptr, cp, bytes);
393 }
394 }
395 if (period_elapsed)
396 snd_pcm_period_elapsed(subs->pcm_substream);
397 return 0;
398}
399
400/*
401 * Process after capture complete when paused. Nothing to do.
402 */
403static int retire_paused_capture_urb(struct snd_usb_substream *subs,
404 struct snd_pcm_runtime *runtime,
405 struct urb *urb)
406{
407 return 0;
408}
409
410
411/*
412 * prepare urb for full speed playback sync pipe
413 *
414 * set up the offset and length to receive the current frequency.
415 */
416
417static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
418 struct snd_pcm_runtime *runtime,
419 struct urb *urb)
420{
421 struct snd_urb_ctx *ctx = urb->context;
422
423 urb->dev = ctx->subs->dev; /* we need to set this at each time */
424 urb->iso_frame_desc[0].length = 3;
425 urb->iso_frame_desc[0].offset = 0;
426 return 0;
427}
428
429/*
430 * prepare urb for high speed playback sync pipe
431 *
432 * set up the offset and length to receive the current frequency.
433 */
434
435static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
436 struct snd_pcm_runtime *runtime,
437 struct urb *urb)
438{
439 struct snd_urb_ctx *ctx = urb->context;
440
441 urb->dev = ctx->subs->dev; /* we need to set this at each time */
442 urb->iso_frame_desc[0].length = 4;
443 urb->iso_frame_desc[0].offset = 0;
444 return 0;
445}
446
447/*
448 * process after full speed playback sync complete
449 *
450 * retrieve the current 10.14 frequency from pipe, and set it.
451 * the value is referred in prepare_playback_urb().
452 */
453static int retire_playback_sync_urb(struct snd_usb_substream *subs,
454 struct snd_pcm_runtime *runtime,
455 struct urb *urb)
456{
457 unsigned int f;
458 unsigned long flags;
459
460 if (urb->iso_frame_desc[0].status == 0 &&
461 urb->iso_frame_desc[0].actual_length == 3) {
462 f = combine_triple((u8*)urb->transfer_buffer) << 2;
463 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
464 spin_lock_irqsave(&subs->lock, flags);
465 subs->freqm = f;
466 spin_unlock_irqrestore(&subs->lock, flags);
467 }
468 }
469
470 return 0;
471}
472
473/*
474 * process after high speed playback sync complete
475 *
476 * retrieve the current 12.13 frequency from pipe, and set it.
477 * the value is referred in prepare_playback_urb().
478 */
479static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
480 struct snd_pcm_runtime *runtime,
481 struct urb *urb)
482{
483 unsigned int f;
484 unsigned long flags;
485
486 if (urb->iso_frame_desc[0].status == 0 &&
487 urb->iso_frame_desc[0].actual_length == 4) {
488 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
489 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
490 spin_lock_irqsave(&subs->lock, flags);
491 subs->freqm = f;
492 spin_unlock_irqrestore(&subs->lock, flags);
493 }
494 }
495
496 return 0;
497}
498
499/*
500 * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
501 *
502 * These devices return the number of samples per packet instead of the number
503 * of samples per microframe.
504 */
505static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
506 struct snd_pcm_runtime *runtime,
507 struct urb *urb)
508{
509 unsigned int f;
510 unsigned long flags;
511
512 if (urb->iso_frame_desc[0].status == 0 &&
513 urb->iso_frame_desc[0].actual_length == 4) {
514 f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
515 f >>= subs->datainterval;
516 if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
517 spin_lock_irqsave(&subs->lock, flags);
518 subs->freqm = f;
519 spin_unlock_irqrestore(&subs->lock, flags);
520 }
521 }
522
523 return 0;
524}
525
526/* determine the number of frames in the next packet */
527static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
528{
529 if (subs->fill_max)
530 return subs->maxframesize;
531 else {
532 subs->phase = (subs->phase & 0xffff)
533 + (subs->freqm << subs->datainterval);
534 return min(subs->phase >> 16, subs->maxframesize);
535 }
536}
537
538/*
539 * Prepare urb for streaming before playback starts or when paused.
540 *
541 * We don't have any data, so we send silence.
542 */
543static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
544 struct snd_pcm_runtime *runtime,
545 struct urb *urb)
546{
547 unsigned int i, offs, counts;
548 struct snd_urb_ctx *ctx = urb->context;
549 int stride = runtime->frame_bits >> 3;
550
551 offs = 0;
552 urb->dev = ctx->subs->dev;
553 for (i = 0; i < ctx->packets; ++i) {
554 counts = snd_usb_audio_next_packet_size(subs);
555 urb->iso_frame_desc[i].offset = offs * stride;
556 urb->iso_frame_desc[i].length = counts * stride;
557 offs += counts;
558 }
559 urb->number_of_packets = ctx->packets;
560 urb->transfer_buffer_length = offs * stride;
561 memset(urb->transfer_buffer,
562 subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
563 offs * stride);
564 return 0;
565}
566
567/*
568 * prepare urb for playback data pipe
569 *
570 * Since a URB can handle only a single linear buffer, we must use double
571 * buffering when the data to be transferred overflows the buffer boundary.
572 * To avoid inconsistencies when updating hwptr_done, we use double buffering
573 * for all URBs.
574 */
575static int prepare_playback_urb(struct snd_usb_substream *subs,
576 struct snd_pcm_runtime *runtime,
577 struct urb *urb)
578{
579 int i, stride;
580 unsigned int counts, frames, bytes;
581 unsigned long flags;
582 int period_elapsed = 0;
583 struct snd_urb_ctx *ctx = urb->context;
584
585 stride = runtime->frame_bits >> 3;
586
587 frames = 0;
588 urb->dev = ctx->subs->dev; /* we need to set this at each time */
589 urb->number_of_packets = 0;
590 spin_lock_irqsave(&subs->lock, flags);
591 for (i = 0; i < ctx->packets; i++) {
592 counts = snd_usb_audio_next_packet_size(subs);
593 /* set up descriptor */
594 urb->iso_frame_desc[i].offset = frames * stride;
595 urb->iso_frame_desc[i].length = counts * stride;
596 frames += counts;
597 urb->number_of_packets++;
598 subs->transfer_done += counts;
599 if (subs->transfer_done >= runtime->period_size) {
600 subs->transfer_done -= runtime->period_size;
601 period_elapsed = 1;
602 if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
603 if (subs->transfer_done > 0) {
604 /* FIXME: fill-max mode is not
605 * supported yet */
606 frames -= subs->transfer_done;
607 counts -= subs->transfer_done;
608 urb->iso_frame_desc[i].length =
609 counts * stride;
610 subs->transfer_done = 0;
611 }
612 i++;
613 if (i < ctx->packets) {
614 /* add a transfer delimiter */
615 urb->iso_frame_desc[i].offset =
616 frames * stride;
617 urb->iso_frame_desc[i].length = 0;
618 urb->number_of_packets++;
619 }
620 break;
621 }
622 }
623 if (period_elapsed) /* finish at the period boundary */
624 break;
625 }
626 bytes = frames * stride;
627 if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
628 /* err, the transferred area goes over buffer boundary. */
629 unsigned int bytes1 =
630 runtime->buffer_size * stride - subs->hwptr_done;
631 memcpy(urb->transfer_buffer,
632 runtime->dma_area + subs->hwptr_done, bytes1);
633 memcpy(urb->transfer_buffer + bytes1,
634 runtime->dma_area, bytes - bytes1);
635 } else {
636 memcpy(urb->transfer_buffer,
637 runtime->dma_area + subs->hwptr_done, bytes);
638 }
639 subs->hwptr_done += bytes;
640 if (subs->hwptr_done >= runtime->buffer_size * stride)
641 subs->hwptr_done -= runtime->buffer_size * stride;
642 runtime->delay += frames;
643 spin_unlock_irqrestore(&subs->lock, flags);
644 urb->transfer_buffer_length = bytes;
645 if (period_elapsed)
646 snd_pcm_period_elapsed(subs->pcm_substream);
647 return 0;
648}
649
650/*
651 * process after playback data complete
652 * - decrease the delay count again
653 */
654static int retire_playback_urb(struct snd_usb_substream *subs,
655 struct snd_pcm_runtime *runtime,
656 struct urb *urb)
657{
658 unsigned long flags;
659 int stride = runtime->frame_bits >> 3;
660 int processed = urb->transfer_buffer_length / stride;
661
662 spin_lock_irqsave(&subs->lock, flags);
663 if (processed > runtime->delay)
664 runtime->delay = 0;
665 else
666 runtime->delay -= processed;
667 spin_unlock_irqrestore(&subs->lock, flags);
668 return 0;
669}
670
671
672/*
673 */
674static struct snd_urb_ops audio_urb_ops[2] = {
675 {
676 .prepare = prepare_nodata_playback_urb,
677 .retire = retire_playback_urb,
678 .prepare_sync = prepare_playback_sync_urb,
679 .retire_sync = retire_playback_sync_urb,
680 },
681 {
682 .prepare = prepare_capture_urb,
683 .retire = retire_capture_urb,
684 .prepare_sync = prepare_capture_sync_urb,
685 .retire_sync = retire_capture_sync_urb,
686 },
687};
688
689static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
690 {
691 .prepare = prepare_nodata_playback_urb,
692 .retire = retire_playback_urb,
693 .prepare_sync = prepare_playback_sync_urb_hs,
694 .retire_sync = retire_playback_sync_urb_hs,
695 },
696 {
697 .prepare = prepare_capture_urb,
698 .retire = retire_capture_urb,
699 .prepare_sync = prepare_capture_sync_urb_hs,
700 .retire_sync = retire_capture_sync_urb,
701 },
702};
703
704/*
705 * complete callback from data urb
706 */
707static void snd_complete_urb(struct urb *urb)
708{
709 struct snd_urb_ctx *ctx = urb->context;
710 struct snd_usb_substream *subs = ctx->subs;
711 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
712 int err = 0;
713
714 if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
715 !subs->running || /* can be stopped during retire callback */
716 (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
717 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
718 clear_bit(ctx->index, &subs->active_mask);
719 if (err < 0) {
720 snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
721 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
722 }
723 }
724}
725
726
727/*
728 * complete callback from sync urb
729 */
730static void snd_complete_sync_urb(struct urb *urb)
731{
732 struct snd_urb_ctx *ctx = urb->context;
733 struct snd_usb_substream *subs = ctx->subs;
734 struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
735 int err = 0;
736
737 if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
738 !subs->running || /* can be stopped during retire callback */
739 (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
740 (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
741 clear_bit(ctx->index + 16, &subs->active_mask);
742 if (err < 0) {
743 snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
744 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
745 }
746 }
747}
748
749
750/*
751 * unlink active urbs.
752 */
753static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
754{
755 unsigned int i;
756 int async;
757
758 subs->running = 0;
759
760 if (!force && subs->stream->chip->shutdown) /* to be sure... */
761 return -EBADFD;
762
763 async = !can_sleep && async_unlink;
764
765 if (!async && in_interrupt())
766 return 0;
767
768 for (i = 0; i < subs->nurbs; i++) {
769 if (test_bit(i, &subs->active_mask)) {
770 if (!test_and_set_bit(i, &subs->unlink_mask)) {
771 struct urb *u = subs->dataurb[i].urb;
772 if (async)
773 usb_unlink_urb(u);
774 else
775 usb_kill_urb(u);
776 }
777 }
778 }
779 if (subs->syncpipe) {
780 for (i = 0; i < SYNC_URBS; i++) {
781 if (test_bit(i+16, &subs->active_mask)) {
782 if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
783 struct urb *u = subs->syncurb[i].urb;
784 if (async)
785 usb_unlink_urb(u);
786 else
787 usb_kill_urb(u);
788 }
789 }
790 }
791 }
792 return 0;
793}
794
795
796static const char *usb_error_string(int err)
797{
798 switch (err) {
799 case -ENODEV:
800 return "no device";
801 case -ENOENT:
802 return "endpoint not enabled";
803 case -EPIPE:
804 return "endpoint stalled";
805 case -ENOSPC:
806 return "not enough bandwidth";
807 case -ESHUTDOWN:
808 return "device disabled";
809 case -EHOSTUNREACH:
810 return "device suspended";
811 case -EINVAL:
812 case -EAGAIN:
813 case -EFBIG:
814 case -EMSGSIZE:
815 return "internal error";
816 default:
817 return "unknown error";
818 }
819}
820
821/*
822 * set up and start data/sync urbs
823 */
824static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
825{
826 unsigned int i;
827 int err;
828
829 if (subs->stream->chip->shutdown)
830 return -EBADFD;
831
832 for (i = 0; i < subs->nurbs; i++) {
833 if (snd_BUG_ON(!subs->dataurb[i].urb))
834 return -EINVAL;
835 if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
836 snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
837 goto __error;
838 }
839 }
840 if (subs->syncpipe) {
841 for (i = 0; i < SYNC_URBS; i++) {
842 if (snd_BUG_ON(!subs->syncurb[i].urb))
843 return -EINVAL;
844 if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
845 snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
846 goto __error;
847 }
848 }
849 }
850
851 subs->active_mask = 0;
852 subs->unlink_mask = 0;
853 subs->running = 1;
854 for (i = 0; i < subs->nurbs; i++) {
855 err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
856 if (err < 0) {
857 snd_printk(KERN_ERR "cannot submit datapipe "
858 "for urb %d, error %d: %s\n",
859 i, err, usb_error_string(err));
860 goto __error;
861 }
862 set_bit(i, &subs->active_mask);
863 }
864 if (subs->syncpipe) {
865 for (i = 0; i < SYNC_URBS; i++) {
866 err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
867 if (err < 0) {
868 snd_printk(KERN_ERR "cannot submit syncpipe "
869 "for urb %d, error %d: %s\n",
870 i, err, usb_error_string(err));
871 goto __error;
872 }
873 set_bit(i + 16, &subs->active_mask);
874 }
875 }
876 return 0;
877
878 __error:
879 // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
880 deactivate_urbs(subs, 0, 0);
881 return -EPIPE;
882}
883
884
885/*
886 * wait until all urbs are processed.
887 */
888static int wait_clear_urbs(struct snd_usb_substream *subs)
889{
890 unsigned long end_time = jiffies + msecs_to_jiffies(1000);
891 unsigned int i;
892 int alive;
893
894 do {
895 alive = 0;
896 for (i = 0; i < subs->nurbs; i++) {
897 if (test_bit(i, &subs->active_mask))
898 alive++;
899 }
900 if (subs->syncpipe) {
901 for (i = 0; i < SYNC_URBS; i++) {
902 if (test_bit(i + 16, &subs->active_mask))
903 alive++;
904 }
905 }
906 if (! alive)
907 break;
908 schedule_timeout_uninterruptible(1);
909 } while (time_before(jiffies, end_time));
910 if (alive)
911 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
912 return 0;
913}
914
915
916/*
917 * return the current pcm pointer. just based on the hwptr_done value.
918 */
919static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
920{
921 struct snd_usb_substream *subs;
922 unsigned int hwptr_done;
923
924 subs = (struct snd_usb_substream *)substream->runtime->private_data;
925 spin_lock(&subs->lock);
926 hwptr_done = subs->hwptr_done;
927 spin_unlock(&subs->lock);
928 return hwptr_done / (substream->runtime->frame_bits >> 3);
929}
930
931
932/*
933 * start/stop playback substream
934 */
935static int snd_usb_pcm_playback_trigger(struct snd_pcm_substream *substream,
936 int cmd)
937{
938 struct snd_usb_substream *subs = substream->runtime->private_data;
939
940 switch (cmd) {
941 case SNDRV_PCM_TRIGGER_START:
942 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
943 subs->ops.prepare = prepare_playback_urb;
944 return 0;
945 case SNDRV_PCM_TRIGGER_STOP:
946 return deactivate_urbs(subs, 0, 0);
947 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
948 subs->ops.prepare = prepare_nodata_playback_urb;
949 return 0;
950 default:
951 return -EINVAL;
952 }
953}
954
955/*
956 * start/stop capture substream
957 */
958static int snd_usb_pcm_capture_trigger(struct snd_pcm_substream *substream,
959 int cmd)
960{
961 struct snd_usb_substream *subs = substream->runtime->private_data;
962
963 switch (cmd) {
964 case SNDRV_PCM_TRIGGER_START:
965 subs->ops.retire = retire_capture_urb;
966 return start_urbs(subs, substream->runtime);
967 case SNDRV_PCM_TRIGGER_STOP:
968 return deactivate_urbs(subs, 0, 0);
969 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
970 subs->ops.retire = retire_paused_capture_urb;
971 return 0;
972 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
973 subs->ops.retire = retire_capture_urb;
974 return 0;
975 default:
976 return -EINVAL;
977 }
978}
979
980
981/*
982 * release a urb data
983 */
984static void release_urb_ctx(struct snd_urb_ctx *u)
985{
986 if (u->urb) {
987 if (u->buffer_size)
988 usb_free_coherent(u->subs->dev, u->buffer_size,
989 u->urb->transfer_buffer,
990 u->urb->transfer_dma);
991 usb_free_urb(u->urb);
992 u->urb = NULL;
993 }
994}
995
996/*
997 * release a substream
998 */
999static void release_substream_urbs(struct snd_usb_substream *subs, int force)
1000{
1001 int i;
1002
1003 /* stop urbs (to be sure) */
1004 deactivate_urbs(subs, force, 1);
1005 wait_clear_urbs(subs);
1006
1007 for (i = 0; i < MAX_URBS; i++)
1008 release_urb_ctx(&subs->dataurb[i]);
1009 for (i = 0; i < SYNC_URBS; i++)
1010 release_urb_ctx(&subs->syncurb[i]);
1011 usb_free_coherent(subs->dev, SYNC_URBS * 4,
1012 subs->syncbuf, subs->sync_dma);
1013 subs->syncbuf = NULL;
1014 subs->nurbs = 0;
1015}
1016
1017/*
1018 * initialize a substream for plaback/capture
1019 */
1020static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes,
1021 unsigned int rate, unsigned int frame_bits)
1022{
1023 unsigned int maxsize, i;
1024 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
1025 unsigned int urb_packs, total_packs, packs_per_ms;
1026
1027 /* calculate the frequency in 16.16 format */
1028 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
1029 subs->freqn = get_usb_full_speed_rate(rate);
1030 else
1031 subs->freqn = get_usb_high_speed_rate(rate);
1032 subs->freqm = subs->freqn;
1033 /* calculate max. frequency */
1034 if (subs->maxpacksize) {
1035 /* whatever fits into a max. size packet */
1036 maxsize = subs->maxpacksize;
1037 subs->freqmax = (maxsize / (frame_bits >> 3))
1038 << (16 - subs->datainterval);
1039 } else {
1040 /* no max. packet size: just take 25% higher than nominal */
1041 subs->freqmax = subs->freqn + (subs->freqn >> 2);
1042 maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
1043 >> (16 - subs->datainterval);
1044 }
1045 subs->phase = 0;
1046
1047 if (subs->fill_max)
1048 subs->curpacksize = subs->maxpacksize;
1049 else
1050 subs->curpacksize = maxsize;
1051
1052 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
1053 packs_per_ms = 8 >> subs->datainterval;
1054 else
1055 packs_per_ms = 1;
1056
1057 if (is_playback) {
1058 urb_packs = max(nrpacks, 1);
1059 urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
1060 } else
1061 urb_packs = 1;
1062 urb_packs *= packs_per_ms;
1063 if (subs->syncpipe)
1064 urb_packs = min(urb_packs, 1U << subs->syncinterval);
1065
1066 /* decide how many packets to be used */
1067 if (is_playback) {
1068 unsigned int minsize, maxpacks;
1069 /* determine how small a packet can be */
1070 minsize = (subs->freqn >> (16 - subs->datainterval))
1071 * (frame_bits >> 3);
1072 /* with sync from device, assume it can be 12% lower */
1073 if (subs->syncpipe)
1074 minsize -= minsize >> 3;
1075 minsize = max(minsize, 1u);
1076 total_packs = (period_bytes + minsize - 1) / minsize;
1077 /* we need at least two URBs for queueing */
1078 if (total_packs < 2) {
1079 total_packs = 2;
1080 } else {
1081 /* and we don't want too long a queue either */
1082 maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
1083 total_packs = min(total_packs, maxpacks);
1084 }
1085 } else {
1086 while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
1087 urb_packs >>= 1;
1088 total_packs = MAX_URBS * urb_packs;
1089 }
1090 subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
1091 if (subs->nurbs > MAX_URBS) {
1092 /* too much... */
1093 subs->nurbs = MAX_URBS;
1094 total_packs = MAX_URBS * urb_packs;
1095 } else if (subs->nurbs < 2) {
1096 /* too little - we need at least two packets
1097 * to ensure contiguous playback/capture
1098 */
1099 subs->nurbs = 2;
1100 }
1101
1102 /* allocate and initialize data urbs */
1103 for (i = 0; i < subs->nurbs; i++) {
1104 struct snd_urb_ctx *u = &subs->dataurb[i];
1105 u->index = i;
1106 u->subs = subs;
1107 u->packets = (i + 1) * total_packs / subs->nurbs
1108 - i * total_packs / subs->nurbs;
1109 u->buffer_size = maxsize * u->packets;
1110 if (subs->fmt_type == UAC_FORMAT_TYPE_II)
1111 u->packets++; /* for transfer delimiter */
1112 u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
1113 if (!u->urb)
1114 goto out_of_memory;
1115 u->urb->transfer_buffer =
1116 usb_alloc_coherent(subs->dev, u->buffer_size, GFP_KERNEL,
1117 &u->urb->transfer_dma);
1118 if (!u->urb->transfer_buffer)
1119 goto out_of_memory;
1120 u->urb->pipe = subs->datapipe;
1121 u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
1122 u->urb->interval = 1 << subs->datainterval;
1123 u->urb->context = u;
1124 u->urb->complete = snd_complete_urb;
1125 }
1126
1127 if (subs->syncpipe) {
1128 /* allocate and initialize sync urbs */
1129 subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
1130 GFP_KERNEL, &subs->sync_dma);
1131 if (!subs->syncbuf)
1132 goto out_of_memory;
1133 for (i = 0; i < SYNC_URBS; i++) {
1134 struct snd_urb_ctx *u = &subs->syncurb[i];
1135 u->index = i;
1136 u->subs = subs;
1137 u->packets = 1;
1138 u->urb = usb_alloc_urb(1, GFP_KERNEL);
1139 if (!u->urb)
1140 goto out_of_memory;
1141 u->urb->transfer_buffer = subs->syncbuf + i * 4;
1142 u->urb->transfer_dma = subs->sync_dma + i * 4;
1143 u->urb->transfer_buffer_length = 4;
1144 u->urb->pipe = subs->syncpipe;
1145 u->urb->transfer_flags = URB_ISO_ASAP |
1146 URB_NO_TRANSFER_DMA_MAP;
1147 u->urb->number_of_packets = 1;
1148 u->urb->interval = 1 << subs->syncinterval;
1149 u->urb->context = u;
1150 u->urb->complete = snd_complete_sync_urb;
1151 }
1152 }
1153 return 0;
1154
1155out_of_memory:
1156 release_substream_urbs(subs, 0);
1157 return -ENOMEM;
1158}
1159
1160
1161/*
1162 * find a matching audio format
1163 */
1164static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
1165 unsigned int rate, unsigned int channels)
1166{
1167 struct list_head *p;
1168 struct audioformat *found = NULL;
1169 int cur_attr = 0, attr;
1170
1171 list_for_each(p, &subs->fmt_list) {
1172 struct audioformat *fp;
1173 fp = list_entry(p, struct audioformat, list);
1174 if (fp->format != format || fp->channels != channels)
1175 continue;
1176 if (rate < fp->rate_min || rate > fp->rate_max)
1177 continue;
1178 if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
1179 unsigned int i;
1180 for (i = 0; i < fp->nr_rates; i++)
1181 if (fp->rate_table[i] == rate)
1182 break;
1183 if (i >= fp->nr_rates)
1184 continue;
1185 }
1186 attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
1187 if (! found) {
1188 found = fp;
1189 cur_attr = attr;
1190 continue;
1191 }
1192 /* avoid async out and adaptive in if the other method
1193 * supports the same format.
1194 * this is a workaround for the case like
1195 * M-audio audiophile USB.
1196 */
1197 if (attr != cur_attr) {
1198 if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
1199 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1200 (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1201 subs->direction == SNDRV_PCM_STREAM_CAPTURE))
1202 continue;
1203 if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
1204 subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
1205 (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
1206 subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
1207 found = fp;
1208 cur_attr = attr;
1209 continue;
1210 }
1211 }
1212 /* find the format with the largest max. packet size */
1213 if (fp->maxpacksize > found->maxpacksize) {
1214 found = fp;
1215 cur_attr = attr;
1216 }
1217 }
1218 return found;
1219}
1220
1221
1222/*
1223 * initialize the picth control and sample rate
1224 */
1225static int init_usb_pitch(struct usb_device *dev, int iface,
1226 struct usb_host_interface *alts,
1227 struct audioformat *fmt)
1228{
1229 unsigned int ep;
1230 unsigned char data[1];
1231 int err;
1232
1233 ep = get_endpoint(alts, 0)->bEndpointAddress;
1234 /* if endpoint has pitch control, enable it */
1235 if (fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL) {
1236 data[0] = 1;
1237 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1238 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1239 UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, data, 1, 1000)) < 0) {
1240 snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
1241 dev->devnum, iface, ep);
1242 return err;
1243 }
1244 }
1245 return 0;
1246}
1247
1248static int init_usb_sample_rate(struct usb_device *dev, int iface,
1249 struct usb_host_interface *alts,
1250 struct audioformat *fmt, int rate)
1251{
1252 unsigned int ep;
1253 unsigned char data[3];
1254 int err;
1255
1256 ep = get_endpoint(alts, 0)->bEndpointAddress;
1257 /* if endpoint has sampling rate control, set it */
1258 if (fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE) {
1259 int crate;
1260 data[0] = rate;
1261 data[1] = rate >> 8;
1262 data[2] = rate >> 16;
1263 if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
1264 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
1265 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1266 snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
1267 dev->devnum, iface, fmt->altsetting, rate, ep);
1268 return err;
1269 }
1270 if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
1271 USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN,
1272 UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000)) < 0) {
1273 snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
1274 dev->devnum, iface, fmt->altsetting, ep);
1275 return 0; /* some devices don't support reading */
1276 }
1277 crate = data[0] | (data[1] << 8) | (data[2] << 16);
1278 if (crate != rate) {
1279 snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
1280 // runtime->rate = crate;
1281 }
1282 }
1283 return 0;
1284}
1285
1286/*
1287 * For E-Mu 0404USB/0202USB/TrackerPre sample rate should be set for device,
1288 * not for interface.
1289 */
1290static void set_format_emu_quirk(struct snd_usb_substream *subs,
1291 struct audioformat *fmt)
1292{
1293 unsigned char emu_samplerate_id = 0;
1294
1295 /* When capture is active
1296 * sample rate shouldn't be changed
1297 * by playback substream
1298 */
1299 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1300 if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
1301 return;
1302 }
1303
1304 switch (fmt->rate_min) {
1305 case 48000:
1306 emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
1307 break;
1308 case 88200:
1309 emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
1310 break;
1311 case 96000:
1312 emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
1313 break;
1314 case 176400:
1315 emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
1316 break;
1317 case 192000:
1318 emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
1319 break;
1320 default:
1321 emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
1322 break;
1323 }
1324 snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
1325}
1326
1327/*
1328 * find a matching format and set up the interface
1329 */
1330static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
1331{
1332 struct usb_device *dev = subs->dev;
1333 struct usb_host_interface *alts;
1334 struct usb_interface_descriptor *altsd;
1335 struct usb_interface *iface;
1336 unsigned int ep, attr;
1337 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
1338 int err;
1339
1340 iface = usb_ifnum_to_if(dev, fmt->iface);
1341 if (WARN_ON(!iface))
1342 return -EINVAL;
1343 alts = &iface->altsetting[fmt->altset_idx];
1344 altsd = get_iface_desc(alts);
1345 if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
1346 return -EINVAL;
1347
1348 if (fmt == subs->cur_audiofmt)
1349 return 0;
1350
1351 /* close the old interface */
1352 if (subs->interface >= 0 && subs->interface != fmt->iface) {
1353 if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
1354 snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
1355 dev->devnum, fmt->iface, fmt->altsetting);
1356 return -EIO;
1357 }
1358 subs->interface = -1;
1359 subs->format = 0;
1360 }
1361
1362 /* set interface */
1363 if (subs->interface != fmt->iface || subs->format != fmt->altset_idx) {
1364 if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
1365 snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
1366 dev->devnum, fmt->iface, fmt->altsetting);
1367 return -EIO;
1368 }
1369 snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
1370 subs->interface = fmt->iface;
1371 subs->format = fmt->altset_idx;
1372 }
1373
1374 /* create a data pipe */
1375 ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
1376 if (is_playback)
1377 subs->datapipe = usb_sndisocpipe(dev, ep);
1378 else
1379 subs->datapipe = usb_rcvisocpipe(dev, ep);
1380 subs->datainterval = fmt->datainterval;
1381 subs->syncpipe = subs->syncinterval = 0;
1382 subs->maxpacksize = fmt->maxpacksize;
1383 subs->fill_max = 0;
1384
1385 /* we need a sync pipe in async OUT or adaptive IN mode */
1386 /* check the number of EP, since some devices have broken
1387 * descriptors which fool us. if it has only one EP,
1388 * assume it as adaptive-out or sync-in.
1389 */
1390 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
1391 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
1392 (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
1393 altsd->bNumEndpoints >= 2) {
1394 /* check sync-pipe endpoint */
1395 /* ... and check descriptor size before accessing bSynchAddress
1396 because there is a version of the SB Audigy 2 NX firmware lacking
1397 the audio fields in the endpoint descriptors */
1398 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
1399 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1400 get_endpoint(alts, 1)->bSynchAddress != 0)) {
1401 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
1402 dev->devnum, fmt->iface, fmt->altsetting);
1403 return -EINVAL;
1404 }
1405 ep = get_endpoint(alts, 1)->bEndpointAddress;
1406 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1407 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
1408 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
1409 snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
1410 dev->devnum, fmt->iface, fmt->altsetting);
1411 return -EINVAL;
1412 }
1413 ep &= USB_ENDPOINT_NUMBER_MASK;
1414 if (is_playback)
1415 subs->syncpipe = usb_rcvisocpipe(dev, ep);
1416 else
1417 subs->syncpipe = usb_sndisocpipe(dev, ep);
1418 if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
1419 get_endpoint(alts, 1)->bRefresh >= 1 &&
1420 get_endpoint(alts, 1)->bRefresh <= 9)
1421 subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
1422 else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
1423 subs->syncinterval = 1;
1424 else if (get_endpoint(alts, 1)->bInterval >= 1 &&
1425 get_endpoint(alts, 1)->bInterval <= 16)
1426 subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
1427 else
1428 subs->syncinterval = 3;
1429 }
1430
1431 /* always fill max packet size */
1432 if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
1433 subs->fill_max = 1;
1434
1435 if ((err = init_usb_pitch(dev, subs->interface, alts, fmt)) < 0)
1436 return err;
1437
1438 subs->cur_audiofmt = fmt;
1439
1440 switch (subs->stream->chip->usb_id) {
1441 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
1442 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
1443 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
1444 set_format_emu_quirk(subs, fmt);
1445 break;
1446 }
1447
1448#if 0
1449 printk(KERN_DEBUG
1450 "setting done: format = %d, rate = %d..%d, channels = %d\n",
1451 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
1452 printk(KERN_DEBUG
1453 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
1454 subs->datapipe, subs->syncpipe);
1455#endif
1456
1457 return 0;
1458}
1459
1460/*
1461 * hw_params callback
1462 *
1463 * allocate a buffer and set the given audio format.
1464 *
1465 * so far we use a physically linear buffer although packetize transfer
1466 * doesn't need a continuous area.
1467 * if sg buffer is supported on the later version of alsa, we'll follow
1468 * that.
1469 */
1470static int snd_usb_hw_params(struct snd_pcm_substream *substream,
1471 struct snd_pcm_hw_params *hw_params)
1472{
1473 struct snd_usb_substream *subs = substream->runtime->private_data;
1474 struct audioformat *fmt;
1475 unsigned int channels, rate, format;
1476 int ret, changed;
1477
1478 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
1479 params_buffer_bytes(hw_params));
1480 if (ret < 0)
1481 return ret;
1482
1483 format = params_format(hw_params);
1484 rate = params_rate(hw_params);
1485 channels = params_channels(hw_params);
1486 fmt = find_format(subs, format, rate, channels);
1487 if (!fmt) {
1488 snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
1489 format, rate, channels);
1490 return -EINVAL;
1491 }
1492
1493 changed = subs->cur_audiofmt != fmt ||
1494 subs->period_bytes != params_period_bytes(hw_params) ||
1495 subs->cur_rate != rate;
1496 if ((ret = set_format(subs, fmt)) < 0)
1497 return ret;
1498
1499 if (subs->cur_rate != rate) {
1500 struct usb_host_interface *alts;
1501 struct usb_interface *iface;
1502 iface = usb_ifnum_to_if(subs->dev, fmt->iface);
1503 alts = &iface->altsetting[fmt->altset_idx];
1504 ret = init_usb_sample_rate(subs->dev, subs->interface, alts, fmt, rate);
1505 if (ret < 0)
1506 return ret;
1507 subs->cur_rate = rate;
1508 }
1509
1510 if (changed) {
1511 /* format changed */
1512 release_substream_urbs(subs, 0);
1513 /* influenced: period_bytes, channels, rate, format, */
1514 ret = init_substream_urbs(subs, params_period_bytes(hw_params),
1515 params_rate(hw_params),
1516 snd_pcm_format_physical_width(params_format(hw_params)) * params_channels(hw_params));
1517 }
1518
1519 return ret;
1520}
1521
1522/*
1523 * hw_free callback
1524 *
1525 * reset the audio format and release the buffer
1526 */
1527static int snd_usb_hw_free(struct snd_pcm_substream *substream)
1528{
1529 struct snd_usb_substream *subs = substream->runtime->private_data;
1530
1531 subs->cur_audiofmt = NULL;
1532 subs->cur_rate = 0;
1533 subs->period_bytes = 0;
1534 if (!subs->stream->chip->shutdown)
1535 release_substream_urbs(subs, 0);
1536 return snd_pcm_lib_free_vmalloc_buffer(substream);
1537}
1538
1539/*
1540 * prepare callback
1541 *
1542 * only a few subtle things...
1543 */
1544static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
1545{
1546 struct snd_pcm_runtime *runtime = substream->runtime;
1547 struct snd_usb_substream *subs = runtime->private_data;
1548
1549 if (! subs->cur_audiofmt) {
1550 snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
1551 return -ENXIO;
1552 }
1553
1554 /* some unit conversions in runtime */
1555 subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
1556 subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
1557
1558 /* reset the pointer */
1559 subs->hwptr_done = 0;
1560 subs->transfer_done = 0;
1561 subs->phase = 0;
1562 runtime->delay = 0;
1563
1564 /* clear urbs (to be sure) */
1565 deactivate_urbs(subs, 0, 1);
1566 wait_clear_urbs(subs);
1567
1568 /* for playback, submit the URBs now; otherwise, the first hwptr_done
1569 * updates for all URBs would happen at the same time when starting */
1570 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
1571 subs->ops.prepare = prepare_nodata_playback_urb;
1572 return start_urbs(subs, runtime);
1573 } else
1574 return 0;
1575}
1576
1577static struct snd_pcm_hardware snd_usb_hardware =
1578{
1579 .info = SNDRV_PCM_INFO_MMAP |
1580 SNDRV_PCM_INFO_MMAP_VALID |
1581 SNDRV_PCM_INFO_BATCH |
1582 SNDRV_PCM_INFO_INTERLEAVED |
1583 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1584 SNDRV_PCM_INFO_PAUSE,
1585 .buffer_bytes_max = 1024 * 1024,
1586 .period_bytes_min = 64,
1587 .period_bytes_max = 512 * 1024,
1588 .periods_min = 2,
1589 .periods_max = 1024,
1590};
1591
1592/*
1593 * h/w constraints
1594 */
1595
1596#ifdef HW_CONST_DEBUG
1597#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
1598#else
1599#define hwc_debug(fmt, args...) /**/
1600#endif
1601
1602static int hw_check_valid_format(struct snd_usb_substream *subs,
1603 struct snd_pcm_hw_params *params,
1604 struct audioformat *fp)
1605{
1606 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1607 struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1608 struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1609 struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
1610 unsigned int ptime;
1611
1612 /* check the format */
1613 if (!snd_mask_test(fmts, fp->format)) {
1614 hwc_debug(" > check: no supported format %d\n", fp->format);
1615 return 0;
1616 }
1617 /* check the channels */
1618 if (fp->channels < ct->min || fp->channels > ct->max) {
1619 hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
1620 return 0;
1621 }
1622 /* check the rate is within the range */
1623 if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
1624 hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
1625 return 0;
1626 }
1627 if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
1628 hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
1629 return 0;
1630 }
1631 /* check whether the period time is >= the data packet interval */
1632 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) {
1633 ptime = 125 * (1 << fp->datainterval);
1634 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
1635 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
1636 return 0;
1637 }
1638 }
1639 return 1;
1640}
1641
1642static int hw_rule_rate(struct snd_pcm_hw_params *params,
1643 struct snd_pcm_hw_rule *rule)
1644{
1645 struct snd_usb_substream *subs = rule->private;
1646 struct list_head *p;
1647 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1648 unsigned int rmin, rmax;
1649 int changed;
1650
1651 hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
1652 changed = 0;
1653 rmin = rmax = 0;
1654 list_for_each(p, &subs->fmt_list) {
1655 struct audioformat *fp;
1656 fp = list_entry(p, struct audioformat, list);
1657 if (!hw_check_valid_format(subs, params, fp))
1658 continue;
1659 if (changed++) {
1660 if (rmin > fp->rate_min)
1661 rmin = fp->rate_min;
1662 if (rmax < fp->rate_max)
1663 rmax = fp->rate_max;
1664 } else {
1665 rmin = fp->rate_min;
1666 rmax = fp->rate_max;
1667 }
1668 }
1669
1670 if (!changed) {
1671 hwc_debug(" --> get empty\n");
1672 it->empty = 1;
1673 return -EINVAL;
1674 }
1675
1676 changed = 0;
1677 if (it->min < rmin) {
1678 it->min = rmin;
1679 it->openmin = 0;
1680 changed = 1;
1681 }
1682 if (it->max > rmax) {
1683 it->max = rmax;
1684 it->openmax = 0;
1685 changed = 1;
1686 }
1687 if (snd_interval_checkempty(it)) {
1688 it->empty = 1;
1689 return -EINVAL;
1690 }
1691 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
1692 return changed;
1693}
1694
1695
1696static int hw_rule_channels(struct snd_pcm_hw_params *params,
1697 struct snd_pcm_hw_rule *rule)
1698{
1699 struct snd_usb_substream *subs = rule->private;
1700 struct list_head *p;
1701 struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1702 unsigned int rmin, rmax;
1703 int changed;
1704
1705 hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
1706 changed = 0;
1707 rmin = rmax = 0;
1708 list_for_each(p, &subs->fmt_list) {
1709 struct audioformat *fp;
1710 fp = list_entry(p, struct audioformat, list);
1711 if (!hw_check_valid_format(subs, params, fp))
1712 continue;
1713 if (changed++) {
1714 if (rmin > fp->channels)
1715 rmin = fp->channels;
1716 if (rmax < fp->channels)
1717 rmax = fp->channels;
1718 } else {
1719 rmin = fp->channels;
1720 rmax = fp->channels;
1721 }
1722 }
1723
1724 if (!changed) {
1725 hwc_debug(" --> get empty\n");
1726 it->empty = 1;
1727 return -EINVAL;
1728 }
1729
1730 changed = 0;
1731 if (it->min < rmin) {
1732 it->min = rmin;
1733 it->openmin = 0;
1734 changed = 1;
1735 }
1736 if (it->max > rmax) {
1737 it->max = rmax;
1738 it->openmax = 0;
1739 changed = 1;
1740 }
1741 if (snd_interval_checkempty(it)) {
1742 it->empty = 1;
1743 return -EINVAL;
1744 }
1745 hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
1746 return changed;
1747}
1748
1749static int hw_rule_format(struct snd_pcm_hw_params *params,
1750 struct snd_pcm_hw_rule *rule)
1751{
1752 struct snd_usb_substream *subs = rule->private;
1753 struct list_head *p;
1754 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1755 u64 fbits;
1756 u32 oldbits[2];
1757 int changed;
1758
1759 hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
1760 fbits = 0;
1761 list_for_each(p, &subs->fmt_list) {
1762 struct audioformat *fp;
1763 fp = list_entry(p, struct audioformat, list);
1764 if (!hw_check_valid_format(subs, params, fp))
1765 continue;
1766 fbits |= (1ULL << fp->format);
1767 }
1768
1769 oldbits[0] = fmt->bits[0];
1770 oldbits[1] = fmt->bits[1];
1771 fmt->bits[0] &= (u32)fbits;
1772 fmt->bits[1] &= (u32)(fbits >> 32);
1773 if (!fmt->bits[0] && !fmt->bits[1]) {
1774 hwc_debug(" --> get empty\n");
1775 return -EINVAL;
1776 }
1777 changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
1778 hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
1779 return changed;
1780}
1781
1782static int hw_rule_period_time(struct snd_pcm_hw_params *params,
1783 struct snd_pcm_hw_rule *rule)
1784{
1785 struct snd_usb_substream *subs = rule->private;
1786 struct audioformat *fp;
1787 struct snd_interval *it;
1788 unsigned char min_datainterval;
1789 unsigned int pmin;
1790 int changed;
1791
1792 it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
1793 hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
1794 min_datainterval = 0xff;
1795 list_for_each_entry(fp, &subs->fmt_list, list) {
1796 if (!hw_check_valid_format(subs, params, fp))
1797 continue;
1798 min_datainterval = min(min_datainterval, fp->datainterval);
1799 }
1800 if (min_datainterval == 0xff) {
1801 hwc_debug(" --> get emtpy\n");
1802 it->empty = 1;
1803 return -EINVAL;
1804 }
1805 pmin = 125 * (1 << min_datainterval);
1806 changed = 0;
1807 if (it->min < pmin) {
1808 it->min = pmin;
1809 it->openmin = 0;
1810 changed = 1;
1811 }
1812 if (snd_interval_checkempty(it)) {
1813 it->empty = 1;
1814 return -EINVAL;
1815 }
1816 hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
1817 return changed;
1818}
1819
1820/*
1821 * If the device supports unusual bit rates, does the request meet these?
1822 */
1823static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
1824 struct snd_usb_substream *subs)
1825{
1826 struct audioformat *fp;
1827 int count = 0, needs_knot = 0;
1828 int err;
1829
1830 list_for_each_entry(fp, &subs->fmt_list, list) {
1831 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
1832 return 0;
1833 count += fp->nr_rates;
1834 if (fp->rates & SNDRV_PCM_RATE_KNOT)
1835 needs_knot = 1;
1836 }
1837 if (!needs_knot)
1838 return 0;
1839
1840 subs->rate_list.count = count;
1841 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
1842 subs->rate_list.mask = 0;
1843 count = 0;
1844 list_for_each_entry(fp, &subs->fmt_list, list) {
1845 int i;
1846 for (i = 0; i < fp->nr_rates; i++)
1847 subs->rate_list.list[count++] = fp->rate_table[i];
1848 }
1849 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1850 &subs->rate_list);
1851 if (err < 0)
1852 return err;
1853
1854 return 0;
1855}
1856
1857
1858/*
1859 * set up the runtime hardware information.
1860 */
1861
1862static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
1863{
1864 struct list_head *p;
1865 unsigned int pt, ptmin;
1866 int param_period_time_if_needed;
1867 int err;
1868
1869 runtime->hw.formats = subs->formats;
1870
1871 runtime->hw.rate_min = 0x7fffffff;
1872 runtime->hw.rate_max = 0;
1873 runtime->hw.channels_min = 256;
1874 runtime->hw.channels_max = 0;
1875 runtime->hw.rates = 0;
1876 ptmin = UINT_MAX;
1877 /* check min/max rates and channels */
1878 list_for_each(p, &subs->fmt_list) {
1879 struct audioformat *fp;
1880 fp = list_entry(p, struct audioformat, list);
1881 runtime->hw.rates |= fp->rates;
1882 if (runtime->hw.rate_min > fp->rate_min)
1883 runtime->hw.rate_min = fp->rate_min;
1884 if (runtime->hw.rate_max < fp->rate_max)
1885 runtime->hw.rate_max = fp->rate_max;
1886 if (runtime->hw.channels_min > fp->channels)
1887 runtime->hw.channels_min = fp->channels;
1888 if (runtime->hw.channels_max < fp->channels)
1889 runtime->hw.channels_max = fp->channels;
1890 if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
1891 /* FIXME: there might be more than one audio formats... */
1892 runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
1893 fp->frame_size;
1894 }
1895 pt = 125 * (1 << fp->datainterval);
1896 ptmin = min(ptmin, pt);
1897 }
1898
1899 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
1900 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH)
1901 /* full speed devices have fixed data packet interval */
1902 ptmin = 1000;
1903 if (ptmin == 1000)
1904 /* if period time doesn't go below 1 ms, no rules needed */
1905 param_period_time_if_needed = -1;
1906 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1907 ptmin, UINT_MAX);
1908
1909 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1910 hw_rule_rate, subs,
1911 SNDRV_PCM_HW_PARAM_FORMAT,
1912 SNDRV_PCM_HW_PARAM_CHANNELS,
1913 param_period_time_if_needed,
1914 -1)) < 0)
1915 return err;
1916 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1917 hw_rule_channels, subs,
1918 SNDRV_PCM_HW_PARAM_FORMAT,
1919 SNDRV_PCM_HW_PARAM_RATE,
1920 param_period_time_if_needed,
1921 -1)) < 0)
1922 return err;
1923 if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
1924 hw_rule_format, subs,
1925 SNDRV_PCM_HW_PARAM_RATE,
1926 SNDRV_PCM_HW_PARAM_CHANNELS,
1927 param_period_time_if_needed,
1928 -1)) < 0)
1929 return err;
1930 if (param_period_time_if_needed >= 0) {
1931 err = snd_pcm_hw_rule_add(runtime, 0,
1932 SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1933 hw_rule_period_time, subs,
1934 SNDRV_PCM_HW_PARAM_FORMAT,
1935 SNDRV_PCM_HW_PARAM_CHANNELS,
1936 SNDRV_PCM_HW_PARAM_RATE,
1937 -1);
1938 if (err < 0)
1939 return err;
1940 }
1941 if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
1942 return err;
1943 return 0;
1944}
1945
1946static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
1947{
1948 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
1949 struct snd_pcm_runtime *runtime = substream->runtime;
1950 struct snd_usb_substream *subs = &as->substream[direction];
1951
1952 subs->interface = -1;
1953 subs->format = 0;
1954 runtime->hw = snd_usb_hardware;
1955 runtime->private_data = subs;
1956 subs->pcm_substream = substream;
1957 return setup_hw_info(runtime, subs);
1958}
1959
1960static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
1961{
1962 struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
1963 struct snd_usb_substream *subs = &as->substream[direction];
1964
1965 if (!as->chip->shutdown && subs->interface >= 0) {
1966 usb_set_interface(subs->dev, subs->interface, 0);
1967 subs->interface = -1;
1968 }
1969 subs->pcm_substream = NULL;
1970 return 0;
1971}
1972
1973static int snd_usb_playback_open(struct snd_pcm_substream *substream)
1974{
1975 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
1976}
1977
1978static int snd_usb_playback_close(struct snd_pcm_substream *substream)
1979{
1980 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
1981}
1982
1983static int snd_usb_capture_open(struct snd_pcm_substream *substream)
1984{
1985 return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
1986}
1987
1988static int snd_usb_capture_close(struct snd_pcm_substream *substream)
1989{
1990 return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
1991}
1992
1993static struct snd_pcm_ops snd_usb_playback_ops = {
1994 .open = snd_usb_playback_open,
1995 .close = snd_usb_playback_close,
1996 .ioctl = snd_pcm_lib_ioctl,
1997 .hw_params = snd_usb_hw_params,
1998 .hw_free = snd_usb_hw_free,
1999 .prepare = snd_usb_pcm_prepare,
2000 .trigger = snd_usb_pcm_playback_trigger,
2001 .pointer = snd_usb_pcm_pointer,
2002 .page = snd_pcm_lib_get_vmalloc_page,
2003 .mmap = snd_pcm_lib_mmap_vmalloc,
2004};
2005
2006static struct snd_pcm_ops snd_usb_capture_ops = {
2007 .open = snd_usb_capture_open,
2008 .close = snd_usb_capture_close,
2009 .ioctl = snd_pcm_lib_ioctl,
2010 .hw_params = snd_usb_hw_params,
2011 .hw_free = snd_usb_hw_free,
2012 .prepare = snd_usb_pcm_prepare,
2013 .trigger = snd_usb_pcm_capture_trigger,
2014 .pointer = snd_usb_pcm_pointer,
2015 .page = snd_pcm_lib_get_vmalloc_page,
2016 .mmap = snd_pcm_lib_mmap_vmalloc,
2017};
2018
2019
2020
2021/*
2022 * helper functions
2023 */
2024
2025/*
2026 * combine bytes and get an integer value
2027 */
2028unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
2029{
2030 switch (size) {
2031 case 1: return *bytes;
2032 case 2: return combine_word(bytes);
2033 case 3: return combine_triple(bytes);
2034 case 4: return combine_quad(bytes);
2035 default: return 0;
2036 }
2037}
2038
2039/*
2040 * parse descriptor buffer and return the pointer starting the given
2041 * descriptor type.
2042 */
2043void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
2044{
2045 u8 *p, *end, *next;
2046
2047 p = descstart;
2048 end = p + desclen;
2049 for (; p < end;) {
2050 if (p[0] < 2)
2051 return NULL;
2052 next = p + p[0];
2053 if (next > end)
2054 return NULL;
2055 if (p[1] == dtype && (!after || (void *)p > after)) {
2056 return p;
2057 }
2058 p = next;
2059 }
2060 return NULL;
2061}
2062
2063/*
2064 * find a class-specified interface descriptor with the given subtype.
2065 */
2066void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
2067{
2068 unsigned char *p = after;
2069
2070 while ((p = snd_usb_find_desc(buffer, buflen, p,
2071 USB_DT_CS_INTERFACE)) != NULL) {
2072 if (p[0] >= 3 && p[2] == dsubtype)
2073 return p;
2074 }
2075 return NULL;
2076}
2077
2078/*
2079 * Wrapper for usb_control_msg().
2080 * Allocates a temp buffer to prevent dmaing from/to the stack.
2081 */
2082int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
2083 __u8 requesttype, __u16 value, __u16 index, void *data,
2084 __u16 size, int timeout)
2085{
2086 int err;
2087 void *buf = NULL;
2088
2089 if (size > 0) {
2090 buf = kmemdup(data, size, GFP_KERNEL);
2091 if (!buf)
2092 return -ENOMEM;
2093 }
2094 err = usb_control_msg(dev, pipe, request, requesttype,
2095 value, index, buf, size, timeout);
2096 if (size > 0) {
2097 memcpy(data, buf, size);
2098 kfree(buf);
2099 }
2100 return err;
2101}
2102
2103
2104/*
2105 * entry point for linux usb interface
2106 */
2107
2108static int usb_audio_probe(struct usb_interface *intf,
2109 const struct usb_device_id *id);
2110static void usb_audio_disconnect(struct usb_interface *intf);
2111
2112#ifdef CONFIG_PM
2113static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message);
2114static int usb_audio_resume(struct usb_interface *intf);
2115#else
2116#define usb_audio_suspend NULL
2117#define usb_audio_resume NULL
2118#endif
2119
2120static struct usb_device_id usb_audio_ids [] = {
2121#include "usbquirks.h"
2122 { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
2123 .bInterfaceClass = USB_CLASS_AUDIO,
2124 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
2125 { } /* Terminating entry */
2126};
2127
2128MODULE_DEVICE_TABLE (usb, usb_audio_ids);
2129
2130static struct usb_driver usb_audio_driver = {
2131 .name = "snd-usb-audio",
2132 .probe = usb_audio_probe,
2133 .disconnect = usb_audio_disconnect,
2134 .suspend = usb_audio_suspend,
2135 .resume = usb_audio_resume,
2136 .id_table = usb_audio_ids,
2137};
2138
2139
2140#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
2141
2142/*
2143 * proc interface for list the supported pcm formats
2144 */
2145static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
2146{
2147 struct list_head *p;
2148 static char *sync_types[4] = {
2149 "NONE", "ASYNC", "ADAPTIVE", "SYNC"
2150 };
2151
2152 list_for_each(p, &subs->fmt_list) {
2153 struct audioformat *fp;
2154 fp = list_entry(p, struct audioformat, list);
2155 snd_iprintf(buffer, " Interface %d\n", fp->iface);
2156 snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
2157 snd_iprintf(buffer, " Format: %s\n",
2158 snd_pcm_format_name(fp->format));
2159 snd_iprintf(buffer, " Channels: %d\n", fp->channels);
2160 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
2161 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
2162 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
2163 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
2164 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
2165 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
2166 fp->rate_min, fp->rate_max);
2167 } else {
2168 unsigned int i;
2169 snd_iprintf(buffer, " Rates: ");
2170 for (i = 0; i < fp->nr_rates; i++) {
2171 if (i > 0)
2172 snd_iprintf(buffer, ", ");
2173 snd_iprintf(buffer, "%d", fp->rate_table[i]);
2174 }
2175 snd_iprintf(buffer, "\n");
2176 }
2177 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
2178 snd_iprintf(buffer, " Data packet interval: %d us\n",
2179 125 * (1 << fp->datainterval));
2180 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
2181 // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
2182 }
2183}
2184
2185static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
2186{
2187 if (subs->running) {
2188 unsigned int i;
2189 snd_iprintf(buffer, " Status: Running\n");
2190 snd_iprintf(buffer, " Interface = %d\n", subs->interface);
2191 snd_iprintf(buffer, " Altset = %d\n", subs->format);
2192 snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs);
2193 for (i = 0; i < subs->nurbs; i++)
2194 snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
2195 snd_iprintf(buffer, "]\n");
2196 snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize);
2197 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
2198 snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
2199 ? get_full_speed_hz(subs->freqm)
2200 : get_high_speed_hz(subs->freqm),
2201 subs->freqm >> 16, subs->freqm & 0xffff);
2202 } else {
2203 snd_iprintf(buffer, " Status: Stop\n");
2204 }
2205}
2206
2207static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
2208{
2209 struct snd_usb_stream *stream = entry->private_data;
2210
2211 snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
2212
2213 if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
2214 snd_iprintf(buffer, "\nPlayback:\n");
2215 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
2216 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
2217 }
2218 if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
2219 snd_iprintf(buffer, "\nCapture:\n");
2220 proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
2221 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
2222 }
2223}
2224
2225static void proc_pcm_format_add(struct snd_usb_stream *stream)
2226{
2227 struct snd_info_entry *entry;
2228 char name[32];
2229 struct snd_card *card = stream->chip->card;
2230
2231 sprintf(name, "stream%d", stream->pcm_index);
2232 if (!snd_card_proc_new(card, name, &entry))
2233 snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
2234}
2235
2236#else
2237
2238static inline void proc_pcm_format_add(struct snd_usb_stream *stream)
2239{
2240}
2241
2242#endif
2243
2244/*
2245 * initialize the substream instance.
2246 */
2247
2248static void init_substream(struct snd_usb_stream *as, int stream, struct audioformat *fp)
2249{
2250 struct snd_usb_substream *subs = &as->substream[stream];
2251
2252 INIT_LIST_HEAD(&subs->fmt_list);
2253 spin_lock_init(&subs->lock);
2254
2255 subs->stream = as;
2256 subs->direction = stream;
2257 subs->dev = as->chip->dev;
2258 subs->txfr_quirk = as->chip->txfr_quirk;
2259 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
2260 subs->ops = audio_urb_ops[stream];
2261 } else {
2262 subs->ops = audio_urb_ops_high_speed[stream];
2263 switch (as->chip->usb_id) {
2264 case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
2265 case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
2266 case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
2267 subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
2268 break;
2269 }
2270 }
2271 snd_pcm_set_ops(as->pcm, stream,
2272 stream == SNDRV_PCM_STREAM_PLAYBACK ?
2273 &snd_usb_playback_ops : &snd_usb_capture_ops);
2274
2275 list_add_tail(&fp->list, &subs->fmt_list);
2276 subs->formats |= 1ULL << fp->format;
2277 subs->endpoint = fp->endpoint;
2278 subs->num_formats++;
2279 subs->fmt_type = fp->fmt_type;
2280}
2281
2282
2283/*
2284 * free a substream
2285 */
2286static void free_substream(struct snd_usb_substream *subs)
2287{
2288 struct list_head *p, *n;
2289
2290 if (!subs->num_formats)
2291 return; /* not initialized */
2292 list_for_each_safe(p, n, &subs->fmt_list) {
2293 struct audioformat *fp = list_entry(p, struct audioformat, list);
2294 kfree(fp->rate_table);
2295 kfree(fp);
2296 }
2297 kfree(subs->rate_list.list);
2298}
2299
2300
2301/*
2302 * free a usb stream instance
2303 */
2304static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
2305{
2306 free_substream(&stream->substream[0]);
2307 free_substream(&stream->substream[1]);
2308 list_del(&stream->list);
2309 kfree(stream);
2310}
2311
2312static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
2313{
2314 struct snd_usb_stream *stream = pcm->private_data;
2315 if (stream) {
2316 stream->pcm = NULL;
2317 snd_usb_audio_stream_free(stream);
2318 }
2319}
2320
2321
2322/*
2323 * add this endpoint to the chip instance.
2324 * if a stream with the same endpoint already exists, append to it.
2325 * if not, create a new pcm stream.
2326 */
2327static int add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp)
2328{
2329 struct list_head *p;
2330 struct snd_usb_stream *as;
2331 struct snd_usb_substream *subs;
2332 struct snd_pcm *pcm;
2333 int err;
2334
2335 list_for_each(p, &chip->pcm_list) {
2336 as = list_entry(p, struct snd_usb_stream, list);
2337 if (as->fmt_type != fp->fmt_type)
2338 continue;
2339 subs = &as->substream[stream];
2340 if (!subs->endpoint)
2341 continue;
2342 if (subs->endpoint == fp->endpoint) {
2343 list_add_tail(&fp->list, &subs->fmt_list);
2344 subs->num_formats++;
2345 subs->formats |= 1ULL << fp->format;
2346 return 0;
2347 }
2348 }
2349 /* look for an empty stream */
2350 list_for_each(p, &chip->pcm_list) {
2351 as = list_entry(p, struct snd_usb_stream, list);
2352 if (as->fmt_type != fp->fmt_type)
2353 continue;
2354 subs = &as->substream[stream];
2355 if (subs->endpoint)
2356 continue;
2357 err = snd_pcm_new_stream(as->pcm, stream, 1);
2358 if (err < 0)
2359 return err;
2360 init_substream(as, stream, fp);
2361 return 0;
2362 }
2363
2364 /* create a new pcm */
2365 as = kzalloc(sizeof(*as), GFP_KERNEL);
2366 if (!as)
2367 return -ENOMEM;
2368 as->pcm_index = chip->pcm_devs;
2369 as->chip = chip;
2370 as->fmt_type = fp->fmt_type;
2371 err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
2372 stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
2373 stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
2374 &pcm);
2375 if (err < 0) {
2376 kfree(as);
2377 return err;
2378 }
2379 as->pcm = pcm;
2380 pcm->private_data = as;
2381 pcm->private_free = snd_usb_audio_pcm_free;
2382 pcm->info_flags = 0;
2383 if (chip->pcm_devs > 0)
2384 sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
2385 else
2386 strcpy(pcm->name, "USB Audio");
2387
2388 init_substream(as, stream, fp);
2389
2390 list_add(&as->list, &chip->pcm_list);
2391 chip->pcm_devs++;
2392
2393 proc_pcm_format_add(as);
2394
2395 return 0;
2396}
2397
2398
2399/*
2400 * check if the device uses big-endian samples
2401 */
2402static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
2403{
2404 switch (chip->usb_id) {
2405 case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
2406 if (fp->endpoint & USB_DIR_IN)
2407 return 1;
2408 break;
2409 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2410 if (device_setup[chip->index] == 0x00 ||
2411 fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
2412 return 1;
2413 }
2414 return 0;
2415}
2416
2417/*
2418 * parse the audio format type I descriptor
2419 * and returns the corresponding pcm format
2420 *
2421 * @dev: usb device
2422 * @fp: audioformat record
2423 * @format: the format tag (wFormatTag)
2424 * @fmt: the format type descriptor
2425 */
2426static int parse_audio_format_i_type(struct snd_usb_audio *chip,
2427 struct audioformat *fp,
2428 int format, void *_fmt,
2429 int protocol)
2430{
2431 int pcm_format, i;
2432 int sample_width, sample_bytes;
2433
2434 switch (protocol) {
2435 case UAC_VERSION_1: {
2436 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2437 sample_width = fmt->bBitResolution;
2438 sample_bytes = fmt->bSubframeSize;
2439 break;
2440 }
2441
2442 case UAC_VERSION_2: {
2443 struct uac_format_type_i_ext_descriptor *fmt = _fmt;
2444 sample_width = fmt->bBitResolution;
2445 sample_bytes = fmt->bSubslotSize;
2446
2447 /*
2448 * FIXME
2449 * USB audio class v2 devices specify a bitmap of possible
2450 * audio formats rather than one fix value. For now, we just
2451 * pick one of them and report that as the only possible
2452 * value for this setting.
2453 * The bit allocation map is in fact compatible to the
2454 * wFormatTag of the v1 AS streaming descriptors, which is why
2455 * we can simply map the matrix.
2456 */
2457
2458 for (i = 0; i < 5; i++)
2459 if (format & (1UL << i)) {
2460 format = i + 1;
2461 break;
2462 }
2463
2464 break;
2465 }
2466
2467 default:
2468 return -EINVAL;
2469 }
2470
2471 /* FIXME: correct endianess and sign? */
2472 pcm_format = -1;
2473
2474 switch (format) {
2475 case UAC_FORMAT_TYPE_I_UNDEFINED: /* some devices don't define this correctly... */
2476 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
2477 chip->dev->devnum, fp->iface, fp->altsetting);
2478 /* fall-through */
2479 case UAC_FORMAT_TYPE_I_PCM:
2480 if (sample_width > sample_bytes * 8) {
2481 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
2482 chip->dev->devnum, fp->iface, fp->altsetting,
2483 sample_width, sample_bytes);
2484 }
2485 /* check the format byte size */
2486 switch (sample_bytes) {
2487 case 1:
2488 pcm_format = SNDRV_PCM_FORMAT_S8;
2489 break;
2490 case 2:
2491 if (is_big_endian_format(chip, fp))
2492 pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */
2493 else
2494 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2495 break;
2496 case 3:
2497 if (is_big_endian_format(chip, fp))
2498 pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */
2499 else
2500 pcm_format = SNDRV_PCM_FORMAT_S24_3LE;
2501 break;
2502 case 4:
2503 pcm_format = SNDRV_PCM_FORMAT_S32_LE;
2504 break;
2505 default:
2506 snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
2507 chip->dev->devnum, fp->iface, fp->altsetting,
2508 sample_width, sample_bytes);
2509 break;
2510 }
2511 break;
2512 case UAC_FORMAT_TYPE_I_PCM8:
2513 pcm_format = SNDRV_PCM_FORMAT_U8;
2514
2515 /* Dallas DS4201 workaround: it advertises U8 format, but really
2516 supports S8. */
2517 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
2518 pcm_format = SNDRV_PCM_FORMAT_S8;
2519 break;
2520 case UAC_FORMAT_TYPE_I_IEEE_FLOAT:
2521 pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE;
2522 break;
2523 case UAC_FORMAT_TYPE_I_ALAW:
2524 pcm_format = SNDRV_PCM_FORMAT_A_LAW;
2525 break;
2526 case UAC_FORMAT_TYPE_I_MULAW:
2527 pcm_format = SNDRV_PCM_FORMAT_MU_LAW;
2528 break;
2529 default:
2530 snd_printk(KERN_INFO "%d:%u:%d : unsupported format type %d\n",
2531 chip->dev->devnum, fp->iface, fp->altsetting, format);
2532 break;
2533 }
2534 return pcm_format;
2535}
2536
2537
2538/*
2539 * parse the format descriptor and stores the possible sample rates
2540 * on the audioformat table (audio class v1).
2541 *
2542 * @dev: usb device
2543 * @fp: audioformat record
2544 * @fmt: the format descriptor
2545 * @offset: the start offset of descriptor pointing the rate type
2546 * (7 for type I and II, 8 for type II)
2547 */
2548static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
2549 unsigned char *fmt, int offset)
2550{
2551 int nr_rates = fmt[offset];
2552
2553 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
2554 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2555 chip->dev->devnum, fp->iface, fp->altsetting);
2556 return -1;
2557 }
2558
2559 if (nr_rates) {
2560 /*
2561 * build the rate table and bitmap flags
2562 */
2563 int r, idx;
2564
2565 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2566 if (fp->rate_table == NULL) {
2567 snd_printk(KERN_ERR "cannot malloc\n");
2568 return -1;
2569 }
2570
2571 fp->nr_rates = 0;
2572 fp->rate_min = fp->rate_max = 0;
2573 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
2574 unsigned int rate = combine_triple(&fmt[idx]);
2575 if (!rate)
2576 continue;
2577 /* C-Media CM6501 mislabels its 96 kHz altsetting */
2578 if (rate == 48000 && nr_rates == 1 &&
2579 (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
2580 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
2581 fp->altsetting == 5 && fp->maxpacksize == 392)
2582 rate = 96000;
2583 /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
2584 if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
2585 rate = 8000;
2586 fp->rate_table[fp->nr_rates] = rate;
2587 if (!fp->rate_min || rate < fp->rate_min)
2588 fp->rate_min = rate;
2589 if (!fp->rate_max || rate > fp->rate_max)
2590 fp->rate_max = rate;
2591 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2592 fp->nr_rates++;
2593 }
2594 if (!fp->nr_rates) {
2595 hwc_debug("All rates were zero. Skipping format!\n");
2596 return -1;
2597 }
2598 } else {
2599 /* continuous rates */
2600 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
2601 fp->rate_min = combine_triple(&fmt[offset + 1]);
2602 fp->rate_max = combine_triple(&fmt[offset + 4]);
2603 }
2604 return 0;
2605}
2606
2607/*
2608 * parse the format descriptor and stores the possible sample rates
2609 * on the audioformat table (audio class v2).
2610 */
2611static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
2612 struct audioformat *fp,
2613 struct usb_host_interface *iface)
2614{
2615 struct usb_device *dev = chip->dev;
2616 unsigned char tmp[2], *data;
2617 int i, nr_rates, data_size, ret = 0;
2618
2619 /* get the number of sample rates first by only fetching 2 bytes */
2620 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
2621 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
2622 0x0100, chip->clock_id << 8, tmp, sizeof(tmp), 1000);
2623
2624 if (ret < 0) {
2625 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n");
2626 goto err;
2627 }
2628
2629 nr_rates = (tmp[1] << 8) | tmp[0];
2630 data_size = 2 + 12 * nr_rates;
2631 data = kzalloc(data_size, GFP_KERNEL);
2632 if (!data) {
2633 ret = -ENOMEM;
2634 goto err;
2635 }
2636
2637 /* now get the full information */
2638 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
2639 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
2640 0x0100, chip->clock_id << 8, data, data_size, 1000);
2641
2642 if (ret < 0) {
2643 snd_printk(KERN_ERR "unable to retrieve sample rate range\n");
2644 ret = -EINVAL;
2645 goto err_free;
2646 }
2647
2648 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2649 if (!fp->rate_table) {
2650 ret = -ENOMEM;
2651 goto err_free;
2652 }
2653
2654 fp->nr_rates = 0;
2655 fp->rate_min = fp->rate_max = 0;
2656
2657 for (i = 0; i < nr_rates; i++) {
2658 int rate = combine_quad(&data[2 + 12 * i]);
2659
2660 fp->rate_table[fp->nr_rates] = rate;
2661 if (!fp->rate_min || rate < fp->rate_min)
2662 fp->rate_min = rate;
2663 if (!fp->rate_max || rate > fp->rate_max)
2664 fp->rate_max = rate;
2665 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2666 fp->nr_rates++;
2667 }
2668
2669err_free:
2670 kfree(data);
2671err:
2672 return ret;
2673}
2674
2675/*
2676 * parse the format type I and III descriptors
2677 */
2678static int parse_audio_format_i(struct snd_usb_audio *chip,
2679 struct audioformat *fp,
2680 int format, void *_fmt,
2681 struct usb_host_interface *iface)
2682{
2683 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2684 struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
2685 int protocol = altsd->bInterfaceProtocol;
2686 int pcm_format, ret;
2687
2688 if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
2689 /* FIXME: the format type is really IECxxx
2690 * but we give normal PCM format to get the existing
2691 * apps working...
2692 */
2693 switch (chip->usb_id) {
2694
2695 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
2696 if (device_setup[chip->index] == 0x00 &&
2697 fp->altsetting == 6)
2698 pcm_format = SNDRV_PCM_FORMAT_S16_BE;
2699 else
2700 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2701 break;
2702 default:
2703 pcm_format = SNDRV_PCM_FORMAT_S16_LE;
2704 }
2705 } else {
2706 pcm_format = parse_audio_format_i_type(chip, fp, format, fmt, protocol);
2707 if (pcm_format < 0)
2708 return -1;
2709 }
2710
2711 fp->format = pcm_format;
2712
2713 /* gather possible sample rates */
2714 /* audio class v1 reports possible sample rates as part of the
2715 * proprietary class specific descriptor.
2716 * audio class v2 uses class specific EP0 range requests for that.
2717 */
2718 switch (protocol) {
2719 case UAC_VERSION_1:
2720 fp->channels = fmt->bNrChannels;
2721 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 7);
2722 break;
2723 case UAC_VERSION_2:
2724 /* fp->channels is already set in this case */
2725 ret = parse_audio_format_rates_v2(chip, fp, iface);
2726 break;
2727 }
2728
2729 if (fp->channels < 1) {
2730 snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
2731 chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
2732 return -1;
2733 }
2734
2735 return ret;
2736}
2737
2738/*
2739 * parse the format type II descriptor
2740 */
2741static int parse_audio_format_ii(struct snd_usb_audio *chip,
2742 struct audioformat *fp,
2743 int format, void *_fmt,
2744 struct usb_host_interface *iface)
2745{
2746 int brate, framesize, ret;
2747 struct usb_interface_descriptor *altsd = get_iface_desc(iface);
2748 int protocol = altsd->bInterfaceProtocol;
2749
2750 switch (format) {
2751 case UAC_FORMAT_TYPE_II_AC3:
2752 /* FIXME: there is no AC3 format defined yet */
2753 // fp->format = SNDRV_PCM_FORMAT_AC3;
2754 fp->format = SNDRV_PCM_FORMAT_U8; /* temporarily hack to receive byte streams */
2755 break;
2756 case UAC_FORMAT_TYPE_II_MPEG:
2757 fp->format = SNDRV_PCM_FORMAT_MPEG;
2758 break;
2759 default:
2760 snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n",
2761 chip->dev->devnum, fp->iface, fp->altsetting, format);
2762 fp->format = SNDRV_PCM_FORMAT_MPEG;
2763 break;
2764 }
2765
2766 fp->channels = 1;
2767
2768 switch (protocol) {
2769 case UAC_VERSION_1: {
2770 struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
2771 brate = le16_to_cpu(fmt->wMaxBitRate);
2772 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2773 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2774 fp->frame_size = framesize;
2775 ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
2776 break;
2777 }
2778 case UAC_VERSION_2: {
2779 struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
2780 brate = le16_to_cpu(fmt->wMaxBitRate);
2781 framesize = le16_to_cpu(fmt->wSamplesPerFrame);
2782 snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
2783 fp->frame_size = framesize;
2784 ret = parse_audio_format_rates_v2(chip, fp, iface);
2785 break;
2786 }
2787 }
2788
2789 return ret;
2790}
2791
2792static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
2793 int format, unsigned char *fmt, int stream,
2794 struct usb_host_interface *iface)
2795{
2796 int err;
2797
2798 switch (fmt[3]) {
2799 case UAC_FORMAT_TYPE_I:
2800 case UAC_FORMAT_TYPE_III:
2801 err = parse_audio_format_i(chip, fp, format, fmt, iface);
2802 break;
2803 case UAC_FORMAT_TYPE_II:
2804 err = parse_audio_format_ii(chip, fp, format, fmt, iface);
2805 break;
2806 default:
2807 snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
2808 chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]);
2809 return -1;
2810 }
2811 fp->fmt_type = fmt[3];
2812 if (err < 0)
2813 return err;
2814#if 1
2815 /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
2816 /* extigy apparently supports sample rates other than 48k
2817 * but not in ordinary way. so we enable only 48k atm.
2818 */
2819 if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
2820 chip->usb_id == USB_ID(0x041e, 0x3020) ||
2821 chip->usb_id == USB_ID(0x041e, 0x3061)) {
2822 if (fmt[3] == UAC_FORMAT_TYPE_I &&
2823 fp->rates != SNDRV_PCM_RATE_48000 &&
2824 fp->rates != SNDRV_PCM_RATE_96000)
2825 return -1;
2826 }
2827#endif
2828 return 0;
2829}
2830
2831static unsigned char parse_datainterval(struct snd_usb_audio *chip,
2832 struct usb_host_interface *alts)
2833{
2834 if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH &&
2835 get_endpoint(alts, 0)->bInterval >= 1 &&
2836 get_endpoint(alts, 0)->bInterval <= 4)
2837 return get_endpoint(alts, 0)->bInterval - 1;
2838 else
2839 return 0;
2840}
2841
2842static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
2843 int iface, int altno);
2844static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
2845{
2846 struct usb_device *dev;
2847 struct usb_interface *iface;
2848 struct usb_host_interface *alts;
2849 struct usb_interface_descriptor *altsd;
2850 int i, altno, err, stream;
2851 int format = 0, num_channels = 0;
2852 struct audioformat *fp = NULL;
2853 unsigned char *fmt, *csep;
2854 int num, protocol;
2855
2856 dev = chip->dev;
2857
2858 /* parse the interface's altsettings */
2859 iface = usb_ifnum_to_if(dev, iface_no);
2860
2861 num = iface->num_altsetting;
2862
2863 /*
2864 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
2865 * one misses syncpipe, and does not produce any sound.
2866 */
2867 if (chip->usb_id == USB_ID(0x04fa, 0x4201))
2868 num = 4;
2869
2870 for (i = 0; i < num; i++) {
2871 alts = &iface->altsetting[i];
2872 altsd = get_iface_desc(alts);
2873 protocol = altsd->bInterfaceProtocol;
2874 /* skip invalid one */
2875 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
2876 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
2877 (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
2878 altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
2879 altsd->bNumEndpoints < 1 ||
2880 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
2881 continue;
2882 /* must be isochronous */
2883 if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
2884 USB_ENDPOINT_XFER_ISOC)
2885 continue;
2886 /* check direction */
2887 stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
2888 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
2889 altno = altsd->bAlternateSetting;
2890
2891 /* audiophile usb: skip altsets incompatible with device_setup
2892 */
2893 if (chip->usb_id == USB_ID(0x0763, 0x2003) &&
2894 audiophile_skip_setting_quirk(chip, iface_no, altno))
2895 continue;
2896
2897 /* get audio formats */
2898 switch (protocol) {
2899 case UAC_VERSION_1: {
2900 struct uac_as_header_descriptor_v1 *as =
2901 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2902
2903 if (!as) {
2904 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
2905 dev->devnum, iface_no, altno);
2906 continue;
2907 }
2908
2909 if (as->bLength < sizeof(*as)) {
2910 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
2911 dev->devnum, iface_no, altno);
2912 continue;
2913 }
2914
2915 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
2916 break;
2917 }
2918
2919 case UAC_VERSION_2: {
2920 struct uac_as_header_descriptor_v2 *as =
2921 snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
2922
2923 if (!as) {
2924 snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
2925 dev->devnum, iface_no, altno);
2926 continue;
2927 }
2928
2929 if (as->bLength < sizeof(*as)) {
2930 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
2931 dev->devnum, iface_no, altno);
2932 continue;
2933 }
2934
2935 num_channels = as->bNrChannels;
2936 format = le32_to_cpu(as->bmFormats);
2937
2938 break;
2939 }
2940
2941 default:
2942 snd_printk(KERN_ERR "%d:%u:%d : unknown interface protocol %04x\n",
2943 dev->devnum, iface_no, altno, protocol);
2944 continue;
2945 }
2946
2947 /* get format type */
2948 fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
2949 if (!fmt) {
2950 snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
2951 dev->devnum, iface_no, altno);
2952 continue;
2953 }
2954 if (((protocol == UAC_VERSION_1) && (fmt[0] < 8)) ||
2955 ((protocol == UAC_VERSION_2) && (fmt[0] != 6))) {
2956 snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
2957 dev->devnum, iface_no, altno);
2958 continue;
2959 }
2960
2961 /*
2962 * Blue Microphones workaround: The last altsetting is identical
2963 * with the previous one, except for a larger packet size, but
2964 * is actually a mislabeled two-channel setting; ignore it.
2965 */
2966 if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
2967 fp && fp->altsetting == 1 && fp->channels == 1 &&
2968 fp->format == SNDRV_PCM_FORMAT_S16_LE &&
2969 protocol == UAC_VERSION_1 &&
2970 le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
2971 fp->maxpacksize * 2)
2972 continue;
2973
2974 csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
2975 /* Creamware Noah has this descriptor after the 2nd endpoint */
2976 if (!csep && altsd->bNumEndpoints >= 2)
2977 csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
2978 if (!csep || csep[0] < 7 || csep[2] != UAC_EP_GENERAL) {
2979 snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
2980 " class specific endpoint descriptor\n",
2981 dev->devnum, iface_no, altno);
2982 csep = NULL;
2983 }
2984
2985 fp = kzalloc(sizeof(*fp), GFP_KERNEL);
2986 if (! fp) {
2987 snd_printk(KERN_ERR "cannot malloc\n");
2988 return -ENOMEM;
2989 }
2990
2991 fp->iface = iface_no;
2992 fp->altsetting = altno;
2993 fp->altset_idx = i;
2994 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
2995 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
2996 fp->datainterval = parse_datainterval(chip, alts);
2997 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
2998 /* num_channels is only set for v2 interfaces */
2999 fp->channels = num_channels;
3000 if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
3001 fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
3002 * (fp->maxpacksize & 0x7ff);
3003 fp->attributes = csep ? csep[3] : 0;
3004
3005 /* some quirks for attributes here */
3006
3007 switch (chip->usb_id) {
3008 case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
3009 /* Optoplay sets the sample rate attribute although
3010 * it seems not supporting it in fact.
3011 */
3012 fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
3013 break;
3014 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
3015 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
3016 /* doesn't set the sample rate attribute, but supports it */
3017 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
3018 break;
3019 case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
3020 case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
3021 an older model 77d:223) */
3022 /*
3023 * plantronics headset and Griffin iMic have set adaptive-in
3024 * although it's really not...
3025 */
3026 fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
3027 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
3028 fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
3029 else
3030 fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
3031 break;
3032 }
3033
3034 /* ok, let's parse further... */
3035 if (parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
3036 kfree(fp->rate_table);
3037 kfree(fp);
3038 continue;
3039 }
3040
3041 snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
3042 err = add_audio_endpoint(chip, stream, fp);
3043 if (err < 0) {
3044 kfree(fp->rate_table);
3045 kfree(fp);
3046 return err;
3047 }
3048 /* try to set the interface... */
3049 usb_set_interface(chip->dev, iface_no, altno);
3050 init_usb_pitch(chip->dev, iface_no, alts, fp);
3051 init_usb_sample_rate(chip->dev, iface_no, alts, fp, fp->rate_max);
3052 }
3053 return 0;
3054}
3055
3056
3057/*
3058 * disconnect streams
3059 * called from snd_usb_audio_disconnect()
3060 */
3061static void snd_usb_stream_disconnect(struct list_head *head)
3062{
3063 int idx;
3064 struct snd_usb_stream *as;
3065 struct snd_usb_substream *subs;
3066
3067 as = list_entry(head, struct snd_usb_stream, list);
3068 for (idx = 0; idx < 2; idx++) {
3069 subs = &as->substream[idx];
3070 if (!subs->num_formats)
3071 return;
3072 release_substream_urbs(subs, 1);
3073 subs->interface = -1;
3074 }
3075}
3076
3077static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
3078{
3079 struct usb_device *dev = chip->dev;
3080 struct usb_host_interface *alts;
3081 struct usb_interface_descriptor *altsd;
3082 struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
3083
3084 if (!iface) {
3085 snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
3086 dev->devnum, ctrlif, interface);
3087 return -EINVAL;
3088 }
3089
3090 if (usb_interface_claimed(iface)) {
3091 snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
3092 dev->devnum, ctrlif, interface);
3093 return -EINVAL;
3094 }
3095
3096 alts = &iface->altsetting[0];
3097 altsd = get_iface_desc(alts);
3098 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
3099 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
3100 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
3101 int err = snd_usbmidi_create(chip->card, iface,
3102 &chip->midi_list, NULL);
3103 if (err < 0) {
3104 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
3105 dev->devnum, ctrlif, interface);
3106 return -EINVAL;
3107 }
3108 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3109
3110 return 0;
3111 }
3112
3113 if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
3114 altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
3115 altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
3116 snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
3117 dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
3118 /* skip non-supported classes */
3119 return -EINVAL;
3120 }
3121
3122 if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
3123 snd_printk(KERN_ERR "low speed audio streaming not supported\n");
3124 return -EINVAL;
3125 }
3126
3127 if (! parse_audio_endpoints(chip, interface)) {
3128 usb_set_interface(dev, interface, 0); /* reset the current interface */
3129 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3130 return -EINVAL;
3131 }
3132
3133 return 0;
3134}
3135
3136/*
3137 * parse audio control descriptor and create pcm/midi streams
3138 */
3139static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
3140{
3141 struct usb_device *dev = chip->dev;
3142 struct usb_host_interface *host_iface;
3143 struct usb_interface_descriptor *altsd;
3144 void *control_header;
3145 int i, protocol;
3146
3147 /* find audiocontrol interface */
3148 host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
3149 control_header = snd_usb_find_csint_desc(host_iface->extra,
3150 host_iface->extralen,
3151 NULL, UAC_HEADER);
3152 altsd = get_iface_desc(host_iface);
3153 protocol = altsd->bInterfaceProtocol;
3154
3155 if (!control_header) {
3156 snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
3157 return -EINVAL;
3158 }
3159
3160 switch (protocol) {
3161 case UAC_VERSION_1: {
3162 struct uac_ac_header_descriptor_v1 *h1 = control_header;
3163
3164 if (!h1->bInCollection) {
3165 snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
3166 return -EINVAL;
3167 }
3168
3169 if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
3170 snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
3171 return -EINVAL;
3172 }
3173
3174 for (i = 0; i < h1->bInCollection; i++)
3175 snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
3176
3177 break;
3178 }
3179
3180 case UAC_VERSION_2: {
3181 struct uac_clock_source_descriptor *cs;
3182 struct usb_interface_assoc_descriptor *assoc =
3183 usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
3184
3185 if (!assoc) {
3186 snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
3187 return -EINVAL;
3188 }
3189
3190 /* FIXME: for now, we expect there is at least one clock source
3191 * descriptor and we always take the first one.
3192 * We should properly support devices with multiple clock sources,
3193 * clock selectors and sample rate conversion units. */
3194
3195 cs = snd_usb_find_csint_desc(host_iface->extra, host_iface->extralen,
3196 NULL, UAC_CLOCK_SOURCE);
3197
3198 if (!cs) {
3199 snd_printk(KERN_ERR "CLOCK_SOURCE descriptor not found\n");
3200 return -EINVAL;
3201 }
3202
3203 chip->clock_id = cs->bClockID;
3204
3205 for (i = 0; i < assoc->bInterfaceCount; i++) {
3206 int intf = assoc->bFirstInterface + i;
3207
3208 if (intf != ctrlif)
3209 snd_usb_create_stream(chip, ctrlif, intf);
3210 }
3211
3212 break;
3213 }
3214
3215 default:
3216 snd_printk(KERN_ERR "unknown protocol version 0x%02x\n", protocol);
3217 return -EINVAL;
3218 }
3219
3220 return 0;
3221}
3222
3223/*
3224 * create a stream for an endpoint/altsetting without proper descriptors
3225 */
3226static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
3227 struct usb_interface *iface,
3228 const struct snd_usb_audio_quirk *quirk)
3229{
3230 struct audioformat *fp;
3231 struct usb_host_interface *alts;
3232 int stream, err;
3233 unsigned *rate_table = NULL;
3234
3235 fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
3236 if (! fp) {
3237 snd_printk(KERN_ERR "cannot memdup\n");
3238 return -ENOMEM;
3239 }
3240 if (fp->nr_rates > 0) {
3241 rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
3242 if (!rate_table) {
3243 kfree(fp);
3244 return -ENOMEM;
3245 }
3246 memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates);
3247 fp->rate_table = rate_table;
3248 }
3249
3250 stream = (fp->endpoint & USB_DIR_IN)
3251 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3252 err = add_audio_endpoint(chip, stream, fp);
3253 if (err < 0) {
3254 kfree(fp);
3255 kfree(rate_table);
3256 return err;
3257 }
3258 if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
3259 fp->altset_idx >= iface->num_altsetting) {
3260 kfree(fp);
3261 kfree(rate_table);
3262 return -EINVAL;
3263 }
3264 alts = &iface->altsetting[fp->altset_idx];
3265 fp->datainterval = parse_datainterval(chip, alts);
3266 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3267 usb_set_interface(chip->dev, fp->iface, 0);
3268 init_usb_pitch(chip->dev, fp->iface, alts, fp);
3269 init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max);
3270 return 0;
3271}
3272
3273/*
3274 * create a stream for an interface with proper descriptors
3275 */
3276static int create_standard_audio_quirk(struct snd_usb_audio *chip,
3277 struct usb_interface *iface,
3278 const struct snd_usb_audio_quirk *quirk)
3279{
3280 struct usb_host_interface *alts;
3281 struct usb_interface_descriptor *altsd;
3282 int err;
3283
3284 alts = &iface->altsetting[0];
3285 altsd = get_iface_desc(alts);
3286 err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
3287 if (err < 0) {
3288 snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
3289 altsd->bInterfaceNumber, err);
3290 return err;
3291 }
3292 /* reset the current interface */
3293 usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
3294 return 0;
3295}
3296
3297/*
3298 * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
3299 * The only way to detect the sample rate is by looking at wMaxPacketSize.
3300 */
3301static int create_uaxx_quirk(struct snd_usb_audio *chip,
3302 struct usb_interface *iface,
3303 const struct snd_usb_audio_quirk *quirk)
3304{
3305 static const struct audioformat ua_format = {
3306 .format = SNDRV_PCM_FORMAT_S24_3LE,
3307 .channels = 2,
3308 .fmt_type = UAC_FORMAT_TYPE_I,
3309 .altsetting = 1,
3310 .altset_idx = 1,
3311 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3312 };
3313 struct usb_host_interface *alts;
3314 struct usb_interface_descriptor *altsd;
3315 struct audioformat *fp;
3316 int stream, err;
3317
3318 /* both PCM and MIDI interfaces have 2 or more altsettings */
3319 if (iface->num_altsetting < 2)
3320 return -ENXIO;
3321 alts = &iface->altsetting[1];
3322 altsd = get_iface_desc(alts);
3323
3324 if (altsd->bNumEndpoints == 2) {
3325 static const struct snd_usb_midi_endpoint_info ua700_ep = {
3326 .out_cables = 0x0003,
3327 .in_cables = 0x0003
3328 };
3329 static const struct snd_usb_audio_quirk ua700_quirk = {
3330 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3331 .data = &ua700_ep
3332 };
3333 static const struct snd_usb_midi_endpoint_info uaxx_ep = {
3334 .out_cables = 0x0001,
3335 .in_cables = 0x0001
3336 };
3337 static const struct snd_usb_audio_quirk uaxx_quirk = {
3338 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3339 .data = &uaxx_ep
3340 };
3341 const struct snd_usb_audio_quirk *quirk =
3342 chip->usb_id == USB_ID(0x0582, 0x002b)
3343 ? &ua700_quirk : &uaxx_quirk;
3344 return snd_usbmidi_create(chip->card, iface,
3345 &chip->midi_list, quirk);
3346 }
3347
3348 if (altsd->bNumEndpoints != 1)
3349 return -ENXIO;
3350
3351 fp = kmalloc(sizeof(*fp), GFP_KERNEL);
3352 if (!fp)
3353 return -ENOMEM;
3354 memcpy(fp, &ua_format, sizeof(*fp));
3355
3356 fp->iface = altsd->bInterfaceNumber;
3357 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3358 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3359 fp->datainterval = 0;
3360 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3361
3362 switch (fp->maxpacksize) {
3363 case 0x120:
3364 fp->rate_max = fp->rate_min = 44100;
3365 break;
3366 case 0x138:
3367 case 0x140:
3368 fp->rate_max = fp->rate_min = 48000;
3369 break;
3370 case 0x258:
3371 case 0x260:
3372 fp->rate_max = fp->rate_min = 96000;
3373 break;
3374 default:
3375 snd_printk(KERN_ERR "unknown sample rate\n");
3376 kfree(fp);
3377 return -ENXIO;
3378 }
3379
3380 stream = (fp->endpoint & USB_DIR_IN)
3381 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3382 err = add_audio_endpoint(chip, stream, fp);
3383 if (err < 0) {
3384 kfree(fp);
3385 return err;
3386 }
3387 usb_set_interface(chip->dev, fp->iface, 0);
3388 return 0;
3389}
3390
3391static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3392 struct usb_interface *iface,
3393 const struct snd_usb_audio_quirk *quirk);
3394
3395/*
3396 * handle the quirks for the contained interfaces
3397 */
3398static int create_composite_quirk(struct snd_usb_audio *chip,
3399 struct usb_interface *iface,
3400 const struct snd_usb_audio_quirk *quirk)
3401{
3402 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
3403 int err;
3404
3405 for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
3406 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
3407 if (!iface)
3408 continue;
3409 if (quirk->ifnum != probed_ifnum &&
3410 usb_interface_claimed(iface))
3411 continue;
3412 err = snd_usb_create_quirk(chip, iface, quirk);
3413 if (err < 0)
3414 return err;
3415 if (quirk->ifnum != probed_ifnum)
3416 usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
3417 }
3418 return 0;
3419}
3420
3421static int ignore_interface_quirk(struct snd_usb_audio *chip,
3422 struct usb_interface *iface,
3423 const struct snd_usb_audio_quirk *quirk)
3424{
3425 return 0;
3426}
3427
3428/*
3429 * Allow alignment on audio sub-slot (channel samples) rather than
3430 * on audio slots (audio frames)
3431 */
3432static int create_align_transfer_quirk(struct snd_usb_audio *chip,
3433 struct usb_interface *iface,
3434 const struct snd_usb_audio_quirk *quirk)
3435{
3436 chip->txfr_quirk = 1;
3437 return 1; /* Continue with creating streams and mixer */
3438}
3439
3440
3441/*
3442 * boot quirks
3443 */
3444
3445#define EXTIGY_FIRMWARE_SIZE_OLD 794
3446#define EXTIGY_FIRMWARE_SIZE_NEW 483
3447
3448static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
3449{
3450 struct usb_host_config *config = dev->actconfig;
3451 int err;
3452
3453 if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
3454 le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
3455 snd_printdd("sending Extigy boot sequence...\n");
3456 /* Send message to force it to reconnect with full interface. */
3457 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
3458 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000);
3459 if (err < 0) snd_printdd("error sending boot message: %d\n", err);
3460 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
3461 &dev->descriptor, sizeof(dev->descriptor));
3462 config = dev->actconfig;
3463 if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
3464 err = usb_reset_configuration(dev);
3465 if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
3466 snd_printdd("extigy_boot: new boot length = %d\n",
3467 le16_to_cpu(get_cfg_desc(config)->wTotalLength));
3468 return -ENODEV; /* quit this anyway */
3469 }
3470 return 0;
3471}
3472
3473static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
3474{
3475 u8 buf = 1;
3476
3477 snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
3478 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
3479 0, 0, &buf, 1, 1000);
3480 if (buf == 0) {
3481 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
3482 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
3483 1, 2000, NULL, 0, 1000);
3484 return -ENODEV;
3485 }
3486 return 0;
3487}
3488
3489/*
3490 * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
3491 * documented in the device's data sheet.
3492 */
3493static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
3494{
3495 u8 buf[4];
3496 buf[0] = 0x20;
3497 buf[1] = value & 0xff;
3498 buf[2] = (value >> 8) & 0xff;
3499 buf[3] = reg;
3500 return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
3501 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
3502 0, 0, &buf, 4, 1000);
3503}
3504
3505static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
3506{
3507 /*
3508 * Enable line-out driver mode, set headphone source to front
3509 * channels, enable stereo mic.
3510 */
3511 return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
3512}
3513
3514/*
3515 * C-Media CM6206 is based on CM106 with two additional
3516 * registers that are not documented in the data sheet.
3517 * Values here are chosen based on sniffing USB traffic
3518 * under Windows.
3519 */
3520static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
3521{
3522 int err, reg;
3523 int val[] = {0x200c, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
3524
3525 for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
3526 err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
3527 if (err < 0)
3528 return err;
3529 }
3530
3531 return err;
3532}
3533
3534/*
3535 * This call will put the synth in "USB send" mode, i.e it will send MIDI
3536 * messages through USB (this is disabled at startup). The synth will
3537 * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
3538 * sign on its LCD. Values here are chosen based on sniffing USB traffic
3539 * under Windows.
3540 */
3541static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
3542{
3543 int err, actual_length;
3544
3545 /* "midi send" enable */
3546 static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
3547
3548 void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
3549 if (!buf)
3550 return -ENOMEM;
3551 err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
3552 ARRAY_SIZE(seq), &actual_length, 1000);
3553 kfree(buf);
3554 if (err < 0)
3555 return err;
3556
3557 return 0;
3558}
3559
3560/*
3561 * Setup quirks
3562 */
3563#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
3564#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
3565#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
3566#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
3567#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
3568#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
3569#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
3570#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
3571#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
3572#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
3573
3574static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
3575 int iface, int altno)
3576{
3577 /* Reset ALL ifaces to 0 altsetting.
3578 * Call it for every possible altsetting of every interface.
3579 */
3580 usb_set_interface(chip->dev, iface, 0);
3581
3582 if (device_setup[chip->index] & AUDIOPHILE_SET) {
3583 if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS)
3584 && altno != 6)
3585 return 1; /* skip this altsetting */
3586 if ((device_setup[chip->index] & AUDIOPHILE_SET_96K)
3587 && altno != 1)
3588 return 1; /* skip this altsetting */
3589 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3590 AUDIOPHILE_SET_24B_48K_DI && altno != 2)
3591 return 1; /* skip this altsetting */
3592 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3593 AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
3594 return 1; /* skip this altsetting */
3595 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3596 AUDIOPHILE_SET_16B_48K_DI && altno != 4)
3597 return 1; /* skip this altsetting */
3598 if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) ==
3599 AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
3600 return 1; /* skip this altsetting */
3601 }
3602 return 0; /* keep this altsetting */
3603}
3604
3605static int create_any_midi_quirk(struct snd_usb_audio *chip,
3606 struct usb_interface *intf,
3607 const struct snd_usb_audio_quirk *quirk)
3608{
3609 return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
3610}
3611
3612/*
3613 * audio-interface quirks
3614 *
3615 * returns zero if no standard audio/MIDI parsing is needed.
3616 * returns a postive value if standard audio/midi interfaces are parsed
3617 * after this.
3618 * returns a negative value at error.
3619 */
3620static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3621 struct usb_interface *iface,
3622 const struct snd_usb_audio_quirk *quirk)
3623{
3624 typedef int (*quirk_func_t)(struct snd_usb_audio *, struct usb_interface *,
3625 const struct snd_usb_audio_quirk *);
3626 static const quirk_func_t quirk_funcs[] = {
3627 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
3628 [QUIRK_COMPOSITE] = create_composite_quirk,
3629 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
3630 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
3631 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
3632 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
3633 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
3634 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk,
3635 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
3636 [QUIRK_MIDI_CME] = create_any_midi_quirk,
3637 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3638 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3639 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
3640 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
3641 };
3642
3643 if (quirk->type < QUIRK_TYPE_COUNT) {
3644 return quirk_funcs[quirk->type](chip, iface, quirk);
3645 } else {
3646 snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
3647 return -ENXIO;
3648 }
3649}
3650
3651
3652/*
3653 * common proc files to show the usb device info
3654 */
3655static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3656{
3657 struct snd_usb_audio *chip = entry->private_data;
3658 if (!chip->shutdown)
3659 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
3660}
3661
3662static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3663{
3664 struct snd_usb_audio *chip = entry->private_data;
3665 if (!chip->shutdown)
3666 snd_iprintf(buffer, "%04x:%04x\n",
3667 USB_ID_VENDOR(chip->usb_id),
3668 USB_ID_PRODUCT(chip->usb_id));
3669}
3670
3671static void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
3672{
3673 struct snd_info_entry *entry;
3674 if (!snd_card_proc_new(chip->card, "usbbus", &entry))
3675 snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
3676 if (!snd_card_proc_new(chip->card, "usbid", &entry))
3677 snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
3678}
3679
3680/*
3681 * free the chip instance
3682 *
3683 * here we have to do not much, since pcm and controls are already freed
3684 *
3685 */
3686
3687static int snd_usb_audio_free(struct snd_usb_audio *chip)
3688{
3689 kfree(chip);
3690 return 0;
3691}
3692
3693static int snd_usb_audio_dev_free(struct snd_device *device)
3694{
3695 struct snd_usb_audio *chip = device->device_data;
3696 return snd_usb_audio_free(chip);
3697}
3698
3699
3700/*
3701 * create a chip instance and set its names.
3702 */
3703static int snd_usb_audio_create(struct usb_device *dev, int idx,
3704 const struct snd_usb_audio_quirk *quirk,
3705 struct snd_usb_audio **rchip)
3706{
3707 struct snd_card *card;
3708 struct snd_usb_audio *chip;
3709 int err, len;
3710 char component[14];
3711 static struct snd_device_ops ops = {
3712 .dev_free = snd_usb_audio_dev_free,
3713 };
3714
3715 *rchip = NULL;
3716
3717 if (snd_usb_get_speed(dev) != USB_SPEED_LOW &&
3718 snd_usb_get_speed(dev) != USB_SPEED_FULL &&
3719 snd_usb_get_speed(dev) != USB_SPEED_HIGH) {
3720 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
3721 return -ENXIO;
3722 }
3723
3724 err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
3725 if (err < 0) {
3726 snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
3727 return err;
3728 }
3729
3730 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
3731 if (! chip) {
3732 snd_card_free(card);
3733 return -ENOMEM;
3734 }
3735
3736 chip->index = idx;
3737 chip->dev = dev;
3738 chip->card = card;
3739 chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3740 le16_to_cpu(dev->descriptor.idProduct));
3741 INIT_LIST_HEAD(&chip->pcm_list);
3742 INIT_LIST_HEAD(&chip->midi_list);
3743 INIT_LIST_HEAD(&chip->mixer_list);
3744
3745 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
3746 snd_usb_audio_free(chip);
3747 snd_card_free(card);
3748 return err;
3749 }
3750
3751 strcpy(card->driver, "USB-Audio");
3752 sprintf(component, "USB%04x:%04x",
3753 USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
3754 snd_component_add(card, component);
3755
3756 /* retrieve the device string as shortname */
3757 if (quirk && quirk->product_name) {
3758 strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
3759 } else {
3760 if (!dev->descriptor.iProduct ||
3761 usb_string(dev, dev->descriptor.iProduct,
3762 card->shortname, sizeof(card->shortname)) <= 0) {
3763 /* no name available from anywhere, so use ID */
3764 sprintf(card->shortname, "USB Device %#04x:%#04x",
3765 USB_ID_VENDOR(chip->usb_id),
3766 USB_ID_PRODUCT(chip->usb_id));
3767 }
3768 }
3769
3770 /* retrieve the vendor and device strings as longname */
3771 if (quirk && quirk->vendor_name) {
3772 len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
3773 } else {
3774 if (dev->descriptor.iManufacturer)
3775 len = usb_string(dev, dev->descriptor.iManufacturer,
3776 card->longname, sizeof(card->longname));
3777 else
3778 len = 0;
3779 /* we don't really care if there isn't any vendor string */
3780 }
3781 if (len > 0)
3782 strlcat(card->longname, " ", sizeof(card->longname));
3783
3784 strlcat(card->longname, card->shortname, sizeof(card->longname));
3785
3786 len = strlcat(card->longname, " at ", sizeof(card->longname));
3787
3788 if (len < sizeof(card->longname))
3789 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
3790
3791 strlcat(card->longname,
3792 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" :
3793 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" :
3794 ", high speed",
3795 sizeof(card->longname));
3796
3797 snd_usb_audio_create_proc(chip);
3798
3799 *rchip = chip;
3800 return 0;
3801}
3802
3803
3804/*
3805 * probe the active usb device
3806 *
3807 * note that this can be called multiple times per a device, when it
3808 * includes multiple audio control interfaces.
3809 *
3810 * thus we check the usb device pointer and creates the card instance
3811 * only at the first time. the successive calls of this function will
3812 * append the pcm interface to the corresponding card.
3813 */
3814static void *snd_usb_audio_probe(struct usb_device *dev,
3815 struct usb_interface *intf,
3816 const struct usb_device_id *usb_id)
3817{
3818 const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
3819 int i, err;
3820 struct snd_usb_audio *chip;
3821 struct usb_host_interface *alts;
3822 int ifnum;
3823 u32 id;
3824
3825 alts = &intf->altsetting[0];
3826 ifnum = get_iface_desc(alts)->bInterfaceNumber;
3827 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
3828 le16_to_cpu(dev->descriptor.idProduct));
3829 if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
3830 goto __err_val;
3831
3832 /* SB Extigy needs special boot-up sequence */
3833 /* if more models come, this will go to the quirk list. */
3834 if (id == USB_ID(0x041e, 0x3000)) {
3835 if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
3836 goto __err_val;
3837 }
3838 /* SB Audigy 2 NX needs its own boot-up magic, too */
3839 if (id == USB_ID(0x041e, 0x3020)) {
3840 if (snd_usb_audigy2nx_boot_quirk(dev) < 0)
3841 goto __err_val;
3842 }
3843
3844 /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
3845 if (id == USB_ID(0x10f5, 0x0200)) {
3846 if (snd_usb_cm106_boot_quirk(dev) < 0)
3847 goto __err_val;
3848 }
3849
3850 /* C-Media CM6206 / CM106-Like Sound Device */
3851 if (id == USB_ID(0x0d8c, 0x0102)) {
3852 if (snd_usb_cm6206_boot_quirk(dev) < 0)
3853 goto __err_val;
3854 }
3855
3856 /* Access Music VirusTI Desktop */
3857 if (id == USB_ID(0x133e, 0x0815)) {
3858 if (snd_usb_accessmusic_boot_quirk(dev) < 0)
3859 goto __err_val;
3860 }
3861
3862 /*
3863 * found a config. now register to ALSA
3864 */
3865
3866 /* check whether it's already registered */
3867 chip = NULL;
3868 mutex_lock(&register_mutex);
3869 for (i = 0; i < SNDRV_CARDS; i++) {
3870 if (usb_chip[i] && usb_chip[i]->dev == dev) {
3871 if (usb_chip[i]->shutdown) {
3872 snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
3873 goto __error;
3874 }
3875 chip = usb_chip[i];
3876 break;
3877 }
3878 }
3879 if (! chip) {
3880 /* it's a fresh one.
3881 * now look for an empty slot and create a new card instance
3882 */
3883 for (i = 0; i < SNDRV_CARDS; i++)
3884 if (enable[i] && ! usb_chip[i] &&
3885 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
3886 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
3887 if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
3888 goto __error;
3889 }
3890 snd_card_set_dev(chip->card, &intf->dev);
3891 break;
3892 }
3893 if (!chip) {
3894 printk(KERN_ERR "no available usb audio device\n");
3895 goto __error;
3896 }
3897 }
3898
3899 chip->txfr_quirk = 0;
3900 err = 1; /* continue */
3901 if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
3902 /* need some special handlings */
3903 if ((err = snd_usb_create_quirk(chip, intf, quirk)) < 0)
3904 goto __error;
3905 }
3906
3907 if (err > 0) {
3908 /* create normal USB audio interfaces */
3909 if (snd_usb_create_streams(chip, ifnum) < 0 ||
3910 snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
3911 goto __error;
3912 }
3913 }
3914
3915 /* we are allowed to call snd_card_register() many times */
3916 if (snd_card_register(chip->card) < 0) {
3917 goto __error;
3918 }
3919
3920 usb_chip[chip->index] = chip;
3921 chip->num_interfaces++;
3922 mutex_unlock(&register_mutex);
3923 return chip;
3924
3925 __error:
3926 if (chip && !chip->num_interfaces)
3927 snd_card_free(chip->card);
3928 mutex_unlock(&register_mutex);
3929 __err_val:
3930 return NULL;
3931}
3932
3933/*
3934 * we need to take care of counter, since disconnection can be called also
3935 * many times as well as usb_audio_probe().
3936 */
3937static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
3938{
3939 struct snd_usb_audio *chip;
3940 struct snd_card *card;
3941 struct list_head *p;
3942
3943 if (ptr == (void *)-1L)
3944 return;
3945
3946 chip = ptr;
3947 card = chip->card;
3948 mutex_lock(&register_mutex);
3949 chip->shutdown = 1;
3950 chip->num_interfaces--;
3951 if (chip->num_interfaces <= 0) {
3952 snd_card_disconnect(card);
3953 /* release the pcm resources */
3954 list_for_each(p, &chip->pcm_list) {
3955 snd_usb_stream_disconnect(p);
3956 }
3957 /* release the midi resources */
3958 list_for_each(p, &chip->midi_list) {
3959 snd_usbmidi_disconnect(p);
3960 }
3961 /* release mixer resources */
3962 list_for_each(p, &chip->mixer_list) {
3963 snd_usb_mixer_disconnect(p);
3964 }
3965 usb_chip[chip->index] = NULL;
3966 mutex_unlock(&register_mutex);
3967 snd_card_free_when_closed(card);
3968 } else {
3969 mutex_unlock(&register_mutex);
3970 }
3971}
3972
3973/*
3974 * new 2.5 USB kernel API
3975 */
3976static int usb_audio_probe(struct usb_interface *intf,
3977 const struct usb_device_id *id)
3978{
3979 void *chip;
3980 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
3981 if (chip) {
3982 usb_set_intfdata(intf, chip);
3983 return 0;
3984 } else
3985 return -EIO;
3986}
3987
3988static void usb_audio_disconnect(struct usb_interface *intf)
3989{
3990 snd_usb_audio_disconnect(interface_to_usbdev(intf),
3991 usb_get_intfdata(intf));
3992}
3993
3994#ifdef CONFIG_PM
3995static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
3996{
3997 struct snd_usb_audio *chip = usb_get_intfdata(intf);
3998 struct list_head *p;
3999 struct snd_usb_stream *as;
4000
4001 if (chip == (void *)-1L)
4002 return 0;
4003
4004 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
4005 if (!chip->num_suspended_intf++) {
4006 list_for_each(p, &chip->pcm_list) {
4007 as = list_entry(p, struct snd_usb_stream, list);
4008 snd_pcm_suspend_all(as->pcm);
4009 }
4010 }
4011
4012 return 0;
4013}
4014
4015static int usb_audio_resume(struct usb_interface *intf)
4016{
4017 struct snd_usb_audio *chip = usb_get_intfdata(intf);
4018
4019 if (chip == (void *)-1L)
4020 return 0;
4021 if (--chip->num_suspended_intf)
4022 return 0;
4023 /*
4024 * ALSA leaves material resumption to user space
4025 * we just notify
4026 */
4027
4028 snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
4029
4030 return 0;
4031}
4032#endif /* CONFIG_PM */
4033
4034static int __init snd_usb_audio_init(void)
4035{
4036 if (nrpacks < 1 || nrpacks > MAX_PACKS) {
4037 printk(KERN_WARNING "invalid nrpacks value.\n");
4038 return -EINVAL;
4039 }
4040 return usb_register(&usb_audio_driver);
4041}
4042
4043
4044static void __exit snd_usb_audio_cleanup(void)
4045{
4046 usb_deregister(&usb_audio_driver);
4047}
4048
4049module_init(snd_usb_audio_init);
4050module_exit(snd_usb_audio_cleanup);
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 42c299cbf63a..d679e72a3e5c 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -21,15 +21,13 @@
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24/* maximum number of endpoints per interface */
25#define MIDI_MAX_ENDPOINTS 2
26
27/* handling of USB vendor/product ID pairs as 32-bit numbers */ 24/* handling of USB vendor/product ID pairs as 32-bit numbers */
28#define USB_ID(vendor, product) (((vendor) << 16) | (product)) 25#define USB_ID(vendor, product) (((vendor) << 16) | (product))
29#define USB_ID_VENDOR(id) ((id) >> 16) 26#define USB_ID_VENDOR(id) ((id) >> 16)
30#define USB_ID_PRODUCT(id) ((u16)(id)) 27#define USB_ID_PRODUCT(id) ((u16)(id))
31 28
32/* 29/*
30 *
33 */ 31 */
34 32
35struct snd_usb_audio { 33struct snd_usb_audio {
@@ -51,6 +49,10 @@ struct snd_usb_audio {
51 struct list_head midi_list; /* list of midi interfaces */ 49 struct list_head midi_list; /* list of midi interfaces */
52 50
53 struct list_head mixer_list; /* list of mixer interfaces */ 51 struct list_head mixer_list; /* list of mixer interfaces */
52
53 int setup; /* from the 'device_setup' module param */
54 int nrpacks; /* from the 'nrpacks' module param */
55 int async_unlink; /* from the 'async_unlink' module param */
54}; 56};
55 57
56/* 58/*
@@ -89,93 +91,8 @@ struct snd_usb_audio_quirk {
89 const void *data; 91 const void *data;
90}; 92};
91 93
92/* data for QUIRK_MIDI_FIXED_ENDPOINT */
93struct snd_usb_midi_endpoint_info {
94 int8_t out_ep; /* ep number, 0 autodetect */
95 uint8_t out_interval; /* interval for interrupt endpoints */
96 int8_t in_ep;
97 uint8_t in_interval;
98 uint16_t out_cables; /* bitmask */
99 uint16_t in_cables; /* bitmask */
100};
101
102/* for QUIRK_MIDI_YAMAHA, data is NULL */
103
104/* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
105 * structure (out_cables and in_cables only) */
106
107/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
108 * structures, terminated with .ifnum = -1 */
109
110/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
111
112/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
113
114/* for QUIRK_AUDIO_EDIROL_UAXX, data is NULL */
115
116/* for QUIRK_IGNORE_INTERFACE, data is NULL */
117
118/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
119
120/* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
121 * structure (out_cables and in_cables only) */
122
123/* for QUIRK_MIDI_CME, data is NULL */
124
125/*
126 */
127
128/*E-mu USB samplerate control quirk*/
129enum {
130 EMU_QUIRK_SR_44100HZ = 0,
131 EMU_QUIRK_SR_48000HZ,
132 EMU_QUIRK_SR_88200HZ,
133 EMU_QUIRK_SR_96000HZ,
134 EMU_QUIRK_SR_176400HZ,
135 EMU_QUIRK_SR_192000HZ
136};
137
138#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8)) 94#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
139#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) 95#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
140#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) 96#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
141 97
142unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
143
144void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
145void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
146
147int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
148 __u8 request, __u8 requesttype, __u16 value, __u16 index,
149 void *data, __u16 size, int timeout);
150
151int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
152 int ignore_error);
153void snd_usb_mixer_disconnect(struct list_head *p);
154
155int snd_usbmidi_create(struct snd_card *card,
156 struct usb_interface *iface,
157 struct list_head *midi_list,
158 const struct snd_usb_audio_quirk *quirk);
159void snd_usbmidi_input_stop(struct list_head* p);
160void snd_usbmidi_input_start(struct list_head* p);
161void snd_usbmidi_disconnect(struct list_head *p);
162
163void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
164 unsigned char samplerate_id);
165
166/*
167 * retrieve usb_interface descriptor from the host interface
168 * (conditional for compatibility with the older API)
169 */
170#ifndef get_iface_desc
171#define get_iface_desc(iface) (&(iface)->desc)
172#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
173#define get_ep_desc(ep) (&(ep)->desc)
174#define get_cfg_desc(cfg) (&(cfg)->desc)
175#endif
176
177#ifndef snd_usb_get_speed
178#define snd_usb_get_speed(dev) ((dev)->speed)
179#endif
180
181#endif /* __USBAUDIO_H */ 98#endif /* __USBAUDIO_H */
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 9ca9a13a78da..6ef68e42138e 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -26,6 +26,7 @@
26#define MODNAME "US122L" 26#define MODNAME "US122L"
27#include "usb_stream.c" 27#include "usb_stream.c"
28#include "../usbaudio.h" 28#include "../usbaudio.h"
29#include "../midi.h"
29#include "us122l.h" 30#include "us122l.h"
30 31
31MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>"); 32MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>");
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index 1d174cea352b..e43c0a86441a 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -1,6 +1,7 @@
1#ifndef USBUSX2Y_H 1#ifndef USBUSX2Y_H
2#define USBUSX2Y_H 2#define USBUSX2Y_H
3#include "../usbaudio.h" 3#include "../usbaudio.h"
4#include "../midi.h"
4#include "usbus428ctldefs.h" 5#include "usbus428ctldefs.h"
5 6
6#define NRURBS 2 7#define NRURBS 2